Loading...

Sunday, May 31, 2009

Use Ivy's dependency mechanisme with Grails

Use Ivy's dependency mechanisme with Grails

Sometimes we need extra dependencies for our Grails application. For example if we use MySQL as a database we need the MySQL Java connector library. With this library we can connect to MySQL in our Grails application. We can add a dependency ourselves by placing the JAR file in the lib directory of our Grails project. But we can also use Ivy to get the dependency for us from the Internet and place it in the lib directory.

First we need to install the Ivy plugin:

$ grails install-plugin ivy

Next we open the file ivy.xml in the root of our Grails project directory. We see a list of dependencies already defined in the file. We remove all dependencies and add the dependency for mysql-connector-java (if we don't remove the other dependencies some libraries will be added twice: once from the list of dependencies defined in ivy.xml and once from the GRAILS_HOME/lib directory):

<ivy-module version="2.0">
    <info organisation="org.example" module="test-1.1.1"/>
    <configurations defaultconfmapping="build->default;compile->compile(*),master(*);test,runtime->runtime(*),master(*)">
        <conf name="build"/>
        <conf name="compile"/>
        <conf name="test" extends="compile"/>
        <conf name="runtime" extends="compile"/>
    </configurations>
    <dependencies>
        <dependency org="mysql" name="mysql-connector-java" rev="5.1.6" conf="runtime"/>
    </dependencies>
</ivy-module>

Now we invoke the get-dependencies tasks from the Ivy plugin to tell Ivy to go out and get all our dependencies and install them in the lib directory:

$ grails get-dependencies

After running this target we look into the lib directory and we see the file mysql-connector-java-5.1.6.jar. We are ready to use a MySQL database and connect to it from our Grails application.

Create a much smaller Grails WAR file without JAR files

The size of a normal Grails WAR file is at least 20MB. The reason is the big list of JAR files which are included in the WEB-INF/lib directory. To exclude all JAR files from the WAR file we can use the command-line argument -nojars. This will even exclude JAR files provided by Grails plugins. The complete command to create the WAR file is:

$ grails war -nojars

We now have a much smaller WAR file (about 200KB for an empty Grails application): a skinny war. This scenario is useful if for example our upload speed is slow. Uploading 20MB can take up to minutes with an ASDL connection. So for a first deployment we can upload the complete WAR file, but for following deployments we can use the small WAR file. Of course we must keep in mind we didn't add new plugins to the application with JAR files, because they will not be added to the WAR file.

Let Grails use Snarl notifications in Windows

Snarl is notification system for Windows and is inspired by Growl. With Snarl applications can send out notifications and Snarl displays them with alpha-blended pop-up windows.

After reading Grails Growl-link notifications in Linux and Grails script notifications via Growl I got inspired to do the same thing for Snarl. First we must of course install Snarl. Next we must download Snarl_CMD.exe. With Snalr_CMD.exe we can display notifications from the command line. So now we create our _Events.grooyv script in <home directory>/.grails/scripts. For each event we want a notification of we invoke the Snarl_CMD.exe command with the correct parameters:

eventStatusFinal = { message ->
    snarlNotification('Final status', message)
}
eventStatusUpdate = { msg ->
    snarlNotification('Status', msg)
} 
eventCreatedFile = { fileName ->
    snarlNotification('Created file', fileName)
}
eventStatusError = { message ->
    snarlNotification('Error', message)
}
eventExiting = { code ->
    snarlNotification('Exit', "Return code $code")
}
eventCreatedArtefact = { type, file ->
    snarlNotification('Created artefct', "$type with name $file")
}
eventCompileStart = { kind ->
    snarlNotification('Compiling', "Compiling $kind")
}
eventCompileEnd = { kind ->
    snarlNotification('Compilation complete', "Compiled $kind")
}
eventPluginInstalled = { pluginName ->
    snarlNotification('Plugin installed', pluginName)
}
void snarlNotification(title, message) {
    def snarlCmd = [
        '<path to Snarl_CMD.exe>/Snarl_CMD.exe',
        'snShowMessage',
        '10', // Display notification for 10 seconds
        "$title", 
        "$message",
        '<GRAILS_HOME>/media/icons/grails - 32x32 icon.png' // Nice icon to show with notification
    ]
    snarlCmd.execute()
}

Now when we run for example grails run-app we get a Snarl notification:

Add "Open with jEdit" to Windows registry

Right-clicking on a file in Windows and selecting "Open with jEdit" is very easy to quickly edit files. jEdit can make the correct setting in our Windows registry during installation. But what if you've just unzipped the zip file and didn't do any installation? We can add the registry key ourselves. We must open Window's regedit. We add the following key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\Open with jEdit\command]
@=<path to javaw.exe> -Xms64M -Xmx192M -jar <path to jEdit directory>\jedit.jar -reuseview "%1"

So we need to add the keys shell, Open with jEdit and command. The default value for command is the path to javaw.exe and jedit.jar.

Saturday, May 30, 2009

Things I don't want to forget about Git

Simple tips for myself for using Git. I am using Cygwin's Git on Windows.

Add remote repository shortcut to make invoking git push repo master possible, instead of typing the complete remote URL each time:

$ git remote add repo ssh://username@severname/~/git-repo

Add files to ignore list by adding files to .git/.gitignore.

Tuesday, May 26, 2009

Automatically generate Javadoc skeleton code in NetBeans

NetBeans can help us with generating a starting point for Javadoc documentation. Suppose we have the following simple Java class:

package javaapplication16;

public class Main {

    public static void main(String[] args) {
        final Main app = new Main();
        app.sayHello("mrhaki");
    }

    public void sayHello(final String name) {
        System.out.println("Hello " + name);
    }

}

We right-click on the Sources Packages and select Tools | Analyze Javadoc.

NetBeans generates a list of all sources files with missing javadoc in the Analyzer window:

We select the files and methods and then hit the Fix Selected button to let NetBeans generate skeleton javadoc code:

package javaapplication16;

/**
 * 
 * @author mrhaki
 */
public class Main {

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        final Main app = new Main();
        app.sayHello("mrhaki");
    }

    /**
     * 
     * @param name
     */
    public void sayHello(final String name) {
        System.out.println("Hello " + name);
    }

}

Now all we have to do is provide meaningful documentation.

Monday, May 25, 2009

Test selection of radio choice options in Wicket

If we want to test the selection of a radio choice we must take some extra steps. After reading this JIRA issue we have a solution:

package com.mrhaki.wicket;

import org.apache.wicket.Component;
import org.apache.wicket.Component.IVisitor;
import org.apache.wicket.markup.html.form.RadioChoice;
import org.apache.wicket.util.tester.FormTester;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Test;

public class PageTest {
  @Test
  public void testRadioChoice() {
    final WicketTester tester = new WicketTester();
    tester.startPage(Page.class);
    final FormTester form = tester.newFormTester("form");
    form.select("radiochoice", 0);
    form.getForm().visitChildren(RadioChoice.class, new IVisitor() {
      public Object component(final Component component) {
        if (component.getId().equals("radiochoice")) {
          ((RadioChoice) component).onSelectionChanged();
        }
        return CONTINUE_TRAVERSAL;
      }
    });
    
    // Do assertion checks here
    // ...
  }
}

Add CSS link in page header for Maven project site

Using Maven's site plugin is very powerful. It is so easy to generate a site with links to documentation and write our own documentation in APT or XDoc format. To keep a consistent look-and-feel it is a good idea to use a CSS file and define the look-and-feel of the site in this file. If we create the file src/site/resources/css/site.css Maven will automatically include it. In the generated pages we find a reference to the site.css:

<style type="text/css" media="all">
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
</style>

Notice the relative reference that is used. This means subprojects or submodules of our Mavenized application cannot reach this file. One way to deal with this is to write our own Maven site skin. We can create the look-and-feel in the site skin and use it among the several submodules.

But what if the company already provides a skin we must use? We cannot use more than one skin, so we need another way out. We add a reference to site.css in our HTML head section which can be recognized by all submodules. In the src/site/site.xml file we add the following:

<body>
  <head>
    <link rel="stylesheet" href="/css/site.css" type="text/css" />
  </head>
</body>

Now all generated pages will have the <link> tag in the HTML head section.

Create new schema/database in MySQL

I always forget these steps, so I have to write them down now. Thanks to this article.

$ mysql -u root -p
mysql> create database dbname;
mysql> grant usage on *.* to user@localhost identified by 'password';
mysql> grant all privileges on dbname.* to user@localhost;

Sunday, May 24, 2009

Wicket component for Java Deployment Toolkit to run applets

Since Java 6 update 10 Sun released the Deployment Toolkit. This kit is a Javascript file that can generate the required HTML to deploy Java applets and Web Start applications. The good thing is the script will take care of all odities between browsers, the applet and embed tags. And we can make sure the minimal Java version for our applet is available on the client's machine. If the required Java version is not available it will be downloaded and installed on the computer.

In this post we see a Wicket component which will replace an applet tag with Javascript. Attributes set for the applet tag are passed on to the Javascript. If we use another HTML element to be replaced, we must programmatically set all attributes.

Let's start with a sample page with the applet tag and a div tag. These tags are replaced with Javascript code by the Wicket component.

<html>
  <head>
  </head>
  <body> 
    <applet wicket:id="applet" code="Applet.class" archive="applet.jar"
      width="100" height="200"/>
    <div wicket:id="appletDiv"/>
  </body>
</html>

We create our Wicket component by extending the org.apache.wicket.markup.html.WebComponent. We then override the onComponentTag and onComponentTagBody methods:

package com.mrhaki.wicket.components;

import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;

public class DeployJava extends WebComponent {
    
    private static final long serialVersionUID = 1L;
    
    public DeployJava(final String id) {
        super(id);
    }

    @Override
    protected void onComponentTag(final ComponentTag tag) {
        super.onComponentTag(tag);
        tag.setName("script");
    }
    
    @Override
    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
        final StringBuilder script = new StringBuilder();
        replaceComponentTagBody(markupStream, openTag, script.toString());
    }
}

This code doesn't do much yet. The only thing we have achieved is that the component will render a script tag with no content. Now it is time to add more functionality. We want to be able to render Javascript like this:

<script>
var attributes = { code: 'Applet.class', archive: 'applet.jar', width: 100, height: 200 };
var parameters = { text: 'Hello world' };
var version = "1.6";
javaDeploy.runApplet(attributes, parameters, version);
</script>

So we start by adding properties in our component to store attributes, parameters and version text. Next we can implement the code in onComponentTagBody to output the Javascript:

...
import net.sf.json.JSONObject;
import org.apache.wicket.util.value.IValueMap;
import org.apache.wicket.util.value.ValueMap;
...
    private String minimalVersion;
    private IValueMap appletAttributes = new ValueMap();
    private IValueMap appletParameters = new ValueMap();
...
    @Override
    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
        final StringBuilder script = new StringBuilder();
        if (appletAttributes.size() > 0) {
            final JSONObject jsonAttributes = JSONObject.fromObject(appletAttributes);
            script.append("var attributes = " + jsonAttributes + ";");
        } else {
            script.append("var attributes = {};");
        }
        if (appletParameters.size() > 0) {
            final JSONObject jsonParameters = JSONObject.fromObject(appletParameters);
            script.append("var parameters = " + jsonParameters + ";");
        } else {
            script.append("var parameters = {};");
        }
        if (minimalVersion != null) {
            script.append("var version = \"" + minimalVersion + "\";");
        } else {
            script.append("var version = null;");
        }
        script.append("deployJava.runApplet(attributes, parameters, version);");
        replaceComponentTagBody(markupStream, openTag, script.toString());
    }
...
    public void setMinimalVersion(final String minimalVersion) {
        this.minimalVersion = minimalVersion;
    }
    
    public void addParameter(final String key, final Object value) {
        appletParameters.put(key, value);
    }
    
    public void addAttributes(final String key, final Object value) {
        appletAttributes.put(key, value);
    }
...

We use the JSON-lib library to convert the attributes and parameters map to Javascript. We also add methods to set values for the properties.

Okay, the component displays the correct Javascript, but we need to add a reference to the Deployment Toolkit Javascript file, otherwise the method deployJava.runApplet is not recognized. We extend the Wicket component and implement the org.apache.wicket.markup.html.IHeaderContributor interface. Wicket components that implement this interface must implement the method renderHead. Wicket will invoke this method and add a Javascript reference in the HTML head section of our web page. For now we simply add a reference to http://java.com/js/deployJava.js.

import org.apache.wicket.markup.html.IHeaderResponse;

public class DeployJava extends WebComponent implements IHeaderContributor {

    public void renderHead(IHeaderResponse response) {
        response.renderJavascriptReference("http://java.com/js/deployJava.js");
    }

}

And that is it for a basic component which renders the correct Javascript. The following code shows a complete component, which can read attributes set on the applet tag and use them in the Javascript. We can also choose between adding the Javascript source file as a Wicket resource or as a reference to the public Sun website URL.

package com.mrhaki.wicket.components;

import net.sf.json.JSONObject;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.resources.CompressedResourceReference;
import org.apache.wicket.util.value.IValueMap;
import org.apache.wicket.util.value.ValueMap;

/**
 * <p>Wicket component to add the 
 * <a href="http://java.sun.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html">Sun's Deployment Toolkit</a>
 * Javascript.
 * The markup can be defined as applet. Attributes defined for the applet are
 * copied to the Javascript. The markup can also be another element, for example
 * a div element.</p>
 * <p>
 * Suppose we have the following applet markup:
 * <pre>
 * &lt;applet wicket:id="applet" width=200 height=120 code="SignatureApplet.class"
 *   archive="codesign.jar"&gt;&lt;/applet&gt;
 * </pre>
 * In a Wicket page we can create this component and add it to the page:
 * <pre>
 * final JavaDeploy javaDeploy = new JavaDeploy("applet");
 * add(javaDeploy);
 * </pre>
 * We get the following output:
 * <pre>
 * &lt;html&gt;
 *   &lt;head&gt;
 *     &lt;script type="text/Javascript" src="http://java.com/js/deployJava.js"&gt;&lt;/script&gt;
 *   &lt;/head&gt;
 *   &lt;body&gt;
 *     &lt;script&gt;
 *     var attributes = { "width":200,"height":120,"code":"SignatureApplet.class","archive":"codesign.jar"};
 *     var parameters = {};
 *     var version = null;
 *     deployJava.runApplet(attributes, parameters, version);
 *     &lt;/script&gt;
 *   &lt;/body&gt;
 * &lt;/html&gt;
 * </pre>
 * </p>
 */
public class DeployJava extends WebComponent implements IHeaderContributor {

    private static final long serialVersionUID = 1L;

    /**
     * Javascript URL on Sun's website for deployJava Javascript. (={@value})
     */
    private static final String JAVASCRIPT_URL = "http://java.com/js/deployJava.js";

    /**
     * Attribute to set the width of the applet. (={@value})
     */
    private static final String ATTRIBUTE_WIDTH = "width";

    /**
     * Attribute to set the height of the applet. (={@value})
     */
    private static final String ATTRIBUTE_HEIGHT = "height";

    /**
     * Attribute to set the applet classname. (={@value})
     */
    private static final String ATTRIBUTE_CODE = "code";

    /**
     * Attribute to set the codebase for the applet. (={@value})
     */
    private static final String ATTRIBUTE_CODEBASE = "codebase";

    /**
     * Attribute to set the archive neede by the applet. (={@value})
     */
    private static final String ATTRIBUTE_ARCHIVE = "archive";

    /**
     * Minimal Java version needed for the applet.
     */
    private String minimalVersion;

    /**
     * If true we use a local resource otherwise the URL from the Sun site.
     * For the local resource we must add the file deployJava.js next to 
     * this class in our package structure.
     */
    private boolean useJavascriptResource;

    /**
     * Attributes for the javaDeploy.runApplet Javascript method.
     */
    private IValueMap appletAttributes = new ValueMap();

    /**
     * Parameters for the javaDeploy.runApplet Javascript method.
     */
    private IValueMap appletParameters = new ValueMap();

    /**
     * Default constructor with markup id.
     *
     * @param id Markup id for applet.
     */
    public DeployJava(String id) {
        super(id);
    }

    /**
     * Minimal Java version for the applet. E.g. Java 1.6 is "1.6".
     *
     * @param version Minimal Java version needed by the applet.
     */
    public void setMinimalVersion(final String version) {
        this.minimalVersion = version;
    }

    /**
     * Width of the applet.
     *
     * @param width Width of the applet on screen.
     */
    public void setWidth(final Integer width) {
        appletAttributes.put(ATTRIBUTE_WIDTH, width);
    }

    /**
     * Height of the applet.
     *
     * @param height Height of the applet on screen.
     */
    public void setHeight(final Integer height) {
        appletAttributes.put(ATTRIBUTE_HEIGHT, height);
    }

    /**
     * Applet classname.
     *
     * @param code Applet classname.
     */
    public void setCode(final String code) {
        appletAttributes.put(ATTRIBUTE_CODE, code);
    }

    /**
     * Codebase for the applet code.
     *
     * @param codebase Codebase for the applet code.
     */
    public void setCodebase(final String codebase) {
        appletAttributes.put(ATTRIBUTE_CODEBASE, codebase);
    }

    /**
     * Archive path for the applet.
     *
     * @param archive Archive location for the applet.
     */
    public void setArchive(final String archive) {
        appletAttributes.put(ATTRIBUTE_ARCHIVE, archive);
    }

    /**
     * Add a parameter to the applet.
     *
     * @param key Name of the parameter.
     * @param value Value for the parameter.
     */
    public void addParameter(final String key, final Object value) {
        appletParameters.put(key, value);
    }

    /**
     * Indicate if deployJava Javascript must be loaded from the Sun site or as local resource.
     *
     * @param useResource True local resource is used, otherwise Sun site.
     */
    public void setUseJavascriptResource(final boolean useResource) {
        this.useJavascriptResource = useResource;
    }

    /**
     * Get the applet attributes already set and assign them to the attribute
     * list for the Javascript code. And we change the tag name to "script".
     *
     * @param tag De current tag which is replaced.
     */
    @Override
    protected void onComponentTag(ComponentTag tag) {
        super.onComponentTag(tag);
        if ("applet".equalsIgnoreCase(tag.getName())) {
            final IValueMap tagAttributes = tag.getAttributes();
            // Save wicket:id so we can add again to the list of attributes.
            final String wicketId = tagAttributes.getString("wicket:id");
            appletAttributes.putAll(tagAttributes);
            tagAttributes.clear();
            tagAttributes.put("wicket:id", wicketId);
        }
        tag.setName("script");
    }

    /**
     * Create Javascript for deployJava.runApplet.
     *
     * @param markupStream MarkupStream to be replaced.
     * @param openTag Tag we are replacing.
     */
    @Override
    protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
        final StringBuilder script = new StringBuilder();
        if (appletAttributes.size() > 0) {
            final JSONObject jsonAttributes = JSONObject.fromObject(appletAttributes);
            script.append("var attributes = " + jsonAttributes + ";");
        } else {
            script.append("var attributes = {};");
        }
        if (appletParameters.size() > 0) {
            final JSONObject jsonParameters = JSONObject.fromObject(appletParameters);
            script.append("var parameters = " + jsonParameters + ";");
        } else {
            script.append("var parameters = {};");
        }
        if (minimalVersion != null) {
            script.append("var version = \"" + minimalVersion + "\";");
        } else {
            script.append("var version = null;");
        }
        script.append("deployJava.runApplet(attributes, parameters, version);");
        replaceComponentTagBody(markupStream, openTag, script.toString());
    }

    /**
     * Add Javascript src reference in the HTML head section of the web page.
     *
     * @param response Header response.
     */
    public void renderHead(IHeaderResponse response) {
        if (useJavascriptResource) {
            response.renderJavascriptReference(new CompressedResourceReference(JavaDeploy.class, "deployJava.js"));
        } else {
            response.renderJavascriptReference(JAVASCRIPT_URL);
        }
    }
}

If we look at the beginning of the post we see the HTML for a web page. We create the code for the page as follows:

package com.mrhaki.wicket.page;

public class AppletPage extends WebPage {

    public AppletPage() {
        final DeployJava applet = new DeployJava("applet");
        add(applet);
        
        final DeployJava div = new DeployJava("appletDiv");
        div.setWidth(100);
        div.setHeight(200);
        div.setCode("NewApplet.class");
        div.setCodeBase("../classes");
        div.addParameter("text", "Hello world");
        div.setMinimalVersion("1.6");
        add(div);
    }
}

When we run the page we get the following HTML:

<html>
  <head>
    <script type="text/javascript" src="http://java.com/js/deployJava.js"></script>
  </head>
  <body>
    <script>
      var attributes = { "code":"Applet.class", "archive":"applet.jar", "width":100, "height":200 };
      var parameters = {};
      var version = null;
      deployJava.runApplet(attributes, parameters, version);
    </script>
    <script>
      var attributes = { "code":"NewApplet.class", "codebaSE":"../classes", "width":100, "height":200 };
      var parameters = { "text":"Hello world" };
      var version = "1.6";
      deployJava.runApplet(attributes, parameters, version);
    </script>
  </body>
</html>

Wednesday, May 20, 2009

Remove trailing spaces in NetBeans

To remove trailing spaces in a source file we go to Source | Remove Trailing Spaces. And that's it.

Tuesday, May 19, 2009

Development JAR signing in Maven

For development purposes we needed to use a signed JAR in our project. First we created a keystore:

$ keytool -genkey -alias applet -keyalg RSA -keystore src/main/keystore/signing-jar.keystore -storepass applet -keypass applet -dname "CN=domain"

We can than use the following Maven POM file definition:

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>sign</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>src/main/keystore/signing-jar.keystore</keystore>
        <alias>applet</alias>
        <storepass>applet</storepass>
        <verify>true</verify>
    </configuration>
</plugin>
...

If we run mvn package we get a signed JAR file. Of course this is only useful for development purposes. To disable the JAR signing we invoke mvn package -Dmaven.jar.sign.skip=true

Include JSON-lib dependency in a Maven project

To include the JSON-lib library as a dependency to our Maven project we must not forget to use the classifier element. Otherwise the library will not be added to our project, because it cannot be downloaded from the repositories.

<dependency>
  <groupId>net.sf.json-lib</groupId>
  <artifactId>json-lib</artifactId>
  <version>2.2.3</version>
  <classifier>jdk15</classifier>
</dependency>

Monday, May 18, 2009

Create new locale properties files with NetBeans

Developing an application with localized messages is something I need to do now and then. Most of the time the messages are defined in a properties file. For each locale we need to create a properties files with the messages. For example if we have a main properties file messages.properties and we want to define messages for the locale nl we must create the file messages_nl.properties. NetBeans supports this scenario with simple commands to quickly create new properties files for different locales.

Suppose we have created a main locale properties file messages.properties. We right-click on the file and select Add | Locale... from the pop-up menu:

NetBeans opens a new dialog window. Here we can select a locale from the list of locales or fill in the correct values ourselves.

When we click the OK button we have a new messages_nl_NL.properties file. In our Project Navigator we can see the new locale as node for the messages.properties file:

Friday, May 15, 2009

Set applet parameter value in Wicket (part 2)

In the previous post we replaced the param elements in Wicket code. Now we will not put the param elements in the markup, but add it dynamically in the Wicket code.

We use the following markup in our HTML template:

<applet wicket:id="appletId"
  code="com.mrhaki.wicket.applet.ApplicationApplet"
  width="100%" height="100%"/>

And the following Java code in our Page class to set the parameters and values for the applet:

add(new WebMarkupContainer("appletId") {
  @Override
  public void onComponentTagBody(MarkupStream markupStream, ComponentTag componentTag) {
    final StringBuilder paramBuilder = new StringBuilder();
    paramBuilder.append("<param name=\"param1\" value=\"" + valueParam1 + "\"/>");
    replaceComponentTagBody(markupStream, openTag, paramBuilder.toString());
  }
});

A more generic Wicket component is also possible.

Thursday, May 14, 2009

Switch between class and test in NetBeans

When we have a Java class in our NetBeans project with a corresponding JUnit test class we can easily switch between them. When we are editing our Java class file and want to go to the test class we select Navigate | Go to Test (Ctrl+Shift+T in Windows). NetBeans jumps to our test class!

To go the other way, we must have our test class open. Now we select Navigate | Go to Tested Class (Ctrl+Shift+T in Windows) and NetBeans jumps to the Java class.

NetBeans assumes the name of the test class starts with the Java class name we want to test, and the package in which both the test class and Java class reside are the same. So for example if we have a Java class com.mrhaki.netbeans.Sample, the test class must be com.mrhaki.netbeans.SampleTest. The files don't have to be in the same directory structure. So the sources can be in a src/ directory and the test classes in a test/ directory.

Wednesday, May 13, 2009

Set applet parameter value in Wicket

A simple solution to set the value for applet parameters in Wicket is by using the WebMarkupContainer. Suppose we have the following applet element in our HTML page:

<applet code="com.mrhaki.wicket.applet.ApplicationApplet" 
    width="100%" height="100%">
    <param name="param1" wicket:id="appletParam1"/>
    <param name="param2" wicket:id="appletParam2"/>
</applet>

In the Page class we can use the following code to set the value for the parameters param1 and param2:

final SimpleAttributeModifer valueParam1 = 
    new SimpleAttributeModifier("value", "Value for param1");
final WebMarkupContainer appletParam1 = new WebMarkupContainer("appletParam1");
appletParam1.add(valueParam1);
add(appletParam1);
add(new WebMarkupContainer("appletParam2").
    add(new SimpleAttributeModifier("value", "Value for param2"));

We see a very expressive way of composing the value for the param element param1. And a very short statement to set the value for the param2 element.

The HTML after Wicket processing is now:


<applet code="com.mrhaki.wicket.applet.ApplicationApplet" 
    width="100%" height="100%">
    <param name="param1" value="Value for param1"/>
    <param name="param2" value="Value for param2"/>
</applet>

Another solution is described in the following post. A more generic Wicket component is also possible.

Working with properties files in NetBeans

Properties files can be part of our Java applications, for example to store configuration settings. In NetBeans we create a new properties file via File | New File... | Other | Properties File. To add properties we simply open the file and add properties as a key=value pair in the editor. But we can use another method: right-click on the properties file and select Add | Property...:

NetBeans opens a small dialog window and we can type the name, value and a comment (optional) for the new property. We click on the OK button to insert the property in our file.

In the Project Navigator we can view all properties in a properties file by clicking on the little arrow in front of the file. We select the property and the editor jumps to right position in the file.

Configure Maven Jetty plugin for SSL communication

For a recent project I had to enable SSL communication for the Maven Jetty plugin. So when we run mvn jetty:run we must be able to use the https protocol. After browsing several mailing list I found the answer. For development we can create our own security certificate and configure the plugin to use it.

To create the development certificate we run the following command:

$ keytool -genkey -alias jetty6 -keyalg RSA -keystore target/jetty-ssl.keystore -storepass jetty6 -keypass jetty6 -dname "CN=your name or domain"

Fill in your name or domain for the -dname "CN=" option. We need the keystore and key password again when we configure the plugin in the Maven POM. The following code fragment shows how the Jetty plugin supports SSL:

<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <configuration>
        <contextPath>/context</contextPath>
        <scanIntervalSeconds>5</scanIntervalSeconds>
        <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                <port>8080</port>
                <maxIdleTime>60000</maxIdleTime>
            </connector>
            <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
                <port>8443</port>
                <maxIdleTime>60000</maxIdleTime>
                <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
                <password>jetty6</password>
                <keyPassword>jetty6</keyPassword>
            </connector>
        </connectors>
    </configuration>
</plugin>

In the connectors element we have defined connectors for http listening on port 8080, and for https listening on port 8443. At line 14 we reference the keystore file we have created with keytool. Lines 15, 16 define the password value.

To test this configuration we can invoke mvn jetty:run and open a web browser with address https://localhost:8443/context. We must not forget to use https for the protocol.

We generated the keystore by using the keytool command from the Java Development Kit. But there is a Maven plugin that does the same thing, but we can define all arguments for keytool in our POM. When we run mvn keytool:genkey the keystore is generated and with mvn keytool:clean we can remove the keystore again. If we want to attach the creation of the keystore to the Maven generate-resources phase we must first make sure we invoke keytool:clean otherwise we get an error from keytool that the specified alias already exists. So we can add the following to our POM:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>keytool-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>generate-resources</phase>
            <id>clean</id>
            <goals>
                <goal>clean</goal>
            </goals>
        </execution>
        <execution>
            <phase>generate-resources</phase>
            <id>genkey</id>
            <goals>
                <goal>genkey</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
        <dname>cn=www.mrhaki.com</dname>
        <keypass>jetty6</keypass>
        <storepass>jetty6</storepass>
        <alias>jetty6</alias>
        <keyalg>RSA</keyalg>
    </configuration>
</plugin>

Now we can invoke mvn jetty:run and the keystore is automatically generated and used by the Jetty plugin.

Tuesday, May 12, 2009

Quickly insert constructors from super class in NetBeans

To quickly insert constructors from a super class in NetBeans we only have to place the cursor in our class and go to Source | Insert Code... (or press Alt+Insert in Windows). For example we create a new Exception class for our application extending the java.lang.Exception class:

package com.mrhaki.netbeans;

public class AppException extends Exception {
    
}

NetBeans shows a pop-up window and we select Constructor....

We get a dialog window with all constructors from the java.lang.Exception class. We select the constructors we want and click on the Generate button.

Now our source code looks like this:

package com.mrhaki.netbeans;

public class AppException extends Exception {

    public AppException(Throwable cause) {
        super(cause);
    }

    public AppException(String message, Throwable cause) {
        super(message, cause);
    }

    public AppException(String message) {
        super(message);
    }

    public AppException() {
    }
    
}

Wednesday, May 6, 2009

Skipping tests from Maven build in NetBeans

In NetBeans we can disable unit testing in a Maven project. I've been working on a project lately with a lot of different modules. Some of these modules contained failing unit test, but there was nothing I could do about it. In order to keep building the modules we can disable the unit testing.

We can define a custom goal for our Maven project. Therefore we must right-click on the project and select Custom | Goals.... NetBeans opens a dialog window. Here we select the checkbox Skip Tests to disable unit testing. We can save this goal with the name build (skip tests).

Now we have the custom goal available if we right-click on the project and go to Custom.

Another way to disable testing is go to Project Properties | Actions. We get the list of actions NetBeans uses and the Maven goals belonging to the actions. We select the Build project action and check the Skip tests checkbox. Now NetBeans will disable unit testing when we invoke the Build project command.

Friday, May 1, 2009

Use anchors in Maven APT project site documentation

Maven supports the APT (Almost Plain Text) format to create documentation. We can even create anchors and links to the anchors in our documentation:

{Simple title}

    We can write our documentation paragraph as always with <<bold>>
    or <italic> text.

{Another section}

    We can link to our {{{Simple_title}Simple title}} section by using the anchor 
    link. We must make sure we replace spaces in an anchor text with underscores.

This will result in the following HTML:

<div class="section"><h2><a name="Simple_title">Simple title</a></h2> 
<p>We can write our documentation paragraph as always with <b>bold</b> or <i>italic</i> text.</p> 
</div> 
<div class="section"><h2><a name="Another_section">Another section</a></h2> 
<p>We can to our <a href="#Simple_title">Simple title</a> section by using the anchor link.</p> 
</div>

Splash screen NetBeans 6.7 beta 1 looks cool

The new splash screen of NetBeans 6.7 beta 1 looks very cool and creative. The only problem is that with NetBeans 6.7 it is only displayed very shortly.