Testing JMX between two Web Applications using Maven

The problem: you have two web applications and each is developed inside a separate Maven module. You need to communicate from one web application to the other and you don't want to implement a service but use JMX instead. This is a scenario we are having here at the moment. The first web application (application A) contains the game server logic of our new game. The second web application (application B) contains a debug tool which we will not deploy into production. I have selected JMX for the communication, mainly because I didn't wanted to add another technology and we are already using JMX in the first application. Both web application are Spring powered.

First here is a nice Spring feature, which completely hides the JMX complexity for the client application behind a proxy.


<bean id="clientConnector" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
<property name="serviceUrl" value="[SERVICE_URL]"/>
</bean>

<bean id="gameplayRecordable" class="org.springframework.jmx.access.MBeanProxyFactoryBean">
<property name="objectName" value="[MBEAN]" />
<property name="proxyInterface" value="any.java.Interface" />
<property name="server" ref="clientConnector" />
</bean>


First you define a client connector which connects you to the RMI server port of the other web application. Then you define a MBeanProxyFactoryBean using this client connector. The objectName must be the name of your MBean inside the MBean container. If you are not sure about the name, use jconsole to connect to the process of the first web application and look it up. Another important property of the MBeanProxyFactoryBean is the proxyInterface. This is an interface that the proxy will implement. The proxy will try to map each method call on that interface in application B to a JMX call in application A. I can really recommend to share the same Interface in both applications as it makes stuff really simple.

This was simple so far. Now lets say you want to write an integration test to automatically test the whole shebang. The test should start up a JMX enabled Jetty from Maven. This Jetty instance should explode the war file of application A (hosting the MBean you want to invoke). Once Jetty is up, the test should execute, connect to application A via the MBeanProxyFactoryBean and validate the results. First lets enable remote JMX access in the configuration of the maven-jetty-plugin:


<profiles>
<profile>
<id>itest</id>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>${version.jetty.plugin}</version>
<configuration>
<stopKey>stop_key</stopKey>
<stopPort>9999</stopPort>
<contextPath>/</contextPath>
<webApp>
${settings.localRepository}/com/package/../../your.war
</webApp>
<jettyConfig>
${basedir}/src/test/etc/jetty-jmx.xml</jettyConfig>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>deploy-war</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>prepare-package</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>


As you can see, this plugin configuration is done in a Maven profile as we are defining this for application B which also has its own Jetty configuration. The important piece is the jettyConfig element which points to a jetty-jmx.xml file. To get this file, download the Jetty container that has the same version as your maven-jetty-plugin. For instance is you use version 6.1.26 of the maven-jetty-plugin, make sure you download jetty-6.1.26 from the codehaus download page. If you are using the the new jetty-maven-plugin and Jetty 7 or 8, you need to download the Jetty container from Eclipse. The configuration is the same for the maven-jetty-plugin and the jetty-maven-plugin. Just make sure you download the jetty-jmx.xml file from the right Jetty container as they are different. You don't need to specify any additional system properties like -Dcom.sun.management.jmxremote, -Dcom.sun.management.jmxremote.ssl, -Dcom.sun.management.jmxremote.authenticate or -Dcom.sun.management.jmxremote.port.

Once the jetty-jmx.xml is downloaded, put in somewhere inside your Maven module where it does not get packaged into the module artifact. In the example above you can see that we have the jetty-jmx.xml file in src/test/etc but any other location will do. Open the file and enable remote JMX access via RMI. In the Jetty 6 based jetty-jmx.xml file these elements should be commented in:


<Call id="rmiRegistry" class="java.rmi.registry.LocateRegistry" name="createRegistry">
<Arg type="int">2099</Arg>
</Call>

<Call id="jmxConnectorServer" class="javax.management.remote.JMXConnectorServerFactory"
name="newJMXConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg>
service:jmx:rmi://localhost:17264/jndi/rmi://localhost:2099/jmxrmi
</Arg>
</New>
</Arg>
<Arg/>
<Arg>
<Ref id="MBeanServer"/>
</Arg>
<Call name="start"/>
</Call>


Note that we changed the port to 17264. You might want to use the default port instead. In the Jetty 7 based jetty-jmx.xml file these elements should be commented in:


<Call name="createRegistry" class="java.rmi.registry.LocateRegistry">
<Arg type="java.lang.Integer">1099</Arg>
<Call name="sleep" class="java.lang.Thread">
<Arg type="java.lang.Integer">1000</Arg>
</Call>
</Call>

<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg type="java.lang.String">rmi</Arg>
<Arg type="java.lang.String" />
<Arg type="java.lang.Integer">0</Arg>
<Arg type="java.lang.String">/jndi/rmi://localhost:1099/jettyjmx</Arg>
</New>
</Arg>
<Arg>org.eclipse.jetty:name=rmiconnectorserver</Arg>
<Call name="start" />
</New>


To test the setup, run mvn -Pitest jetty:run and start jconsole. In jconsole you do not connect to a local process. Select Remote Process and enter the service URL. This URL can be copied from the jetty-jmx.xml file if you are using Jetty 6 (i.e. service:jmx:rmi://localhost:17264/jndi/rmi://localhost:2099/jmxrmi). If you are using Jetty 7 and the jetty-maven-plugin, there will be a info statement on the command line when Maven starts the Jetty container from where you can copy the service URL. Finally to execute the integration test, we use the maven-failsafe-plugin like this:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.9</version>
<configuration>
<includes>
<include>**/com/package/integration/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id> to specify any additional system properties like -Dcom.sun.management.jmxremote, -Dcom.sun.management.jmxremote.ssl, -Dcom.sun.management.jmxremote.authenticate or -Dcom.sun.management.jmxremote.port.

Once the jetty-jmx.xml is downloaded, put in somewhere inside your Maven module where it does not get packaged into the module artifact. In the example above you can see that we have the jetty-jmx.xml file in src/test/etc but any other location will do. Open the file and enable remote JMX access via RMI. In the Jetty 6 based jetty-jmx.xml file these elements should be commented in:


<Call id="rmiRegistry" class="java.rmi.registry.LocateRegistry" name="createRegistry">
<Arg type="int">2099</Arg>
</Call>

<Call id="jmxConnectorServer" class="javax.management.remote.JMXConnectorServerFactory"
name="newJMXConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg>service:jmx:rmi://localhost:17264/jndi/rmi://localhost:2099/jmxrmi</Arg>
</New>
</Arg>
<Arg/>
<Arg>
<Ref id="MBeanServer"/>
</Arg>
<Call name="start"/>
</Call>


Note that we changed the port to 17264. You might want to use the default port instead. In the Jetty 7 based jetty-jmx.xml file these elements should be commented in:


<Call name="createRegistry" class="java.rmi.registry.LocateRegistry">
<Arg type="java.lang.Integer">1099</Arg>
<Call name="sleep" class="java.lang.Thread">
<Arg type="java.lang.Integer">1000</Arg>
</Call>
</Call>

<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg type="java.lang.String">rmi</Arg>
<Arg type="java.lang.String" />
<Arg type="java.lang.Integer">0</Arg>
<Arg type="java.lang.String">/jndi/rmi://localhost:1099/jettyjmx</Arg>
</New>
</Arg>
<Arg>org.eclipse.jetty:name=rmiconnectorserver</Arg>
<Call name="start" />
</New>


To test the setup, run mvn -Pitest jetty:run and start jconsole. In jconsole you do not connect to a local process. Select Remote Process and enter the service URL. This URL can be copied from the jetty-jmx.xml file if you are using Jetty 6 (i.e. service:jmx:rmi://localhost:17264/jndi/rmi://localhost:2099/jmxrmi). If you are using Jetty 7 and the jetty-maven-plugin, there will be a info statement on the command line when Maven starts the Jetty container from where you can copy the service URL. Finally to execute the integration test, we use the maven-failsafe-plugin like this:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.9</version>
<configuration>
<includes>
<include>**/com/package/integration/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>

<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>

Sharing configuration files from a Maven Parent Project

Okay this post is probably not much news for people who know Maven in and out. I am planning to use this as a reference for myself, in the case that I have to solve a similar problem again in the future. The current project I am working with, is set up as a Maven multi module project. There is a parent pom which is set to pom-packaging. There are several child modules, set to either jar- or war-packaging. Within the pom.xml file of the parent project, we use the pluginManagement section to define plugins that should be available to the child modules. The pluginManagement mechanism is an excellent way to avoid the DRY problem and not to duplicate Maven configuration within the inheriting projects.

In most cases configuring plugins within the pluginManagement section is straight forward. It can however get a bit problematic if the plugin depends on (or is reading from external) configuration files. Lets have a look at one example from this parent project of ours.


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.package</groupId>
<artifactId>project-parent</artifactId>
<packaging>pom</packaging>
<version>0.1-SNAPSHOT</version>

<modules>
<module>child-a</module>
<module>child-b</module>
<module>child-c</module>
</modules>

<properties>
<version.mysql.connector>5.1.12</version.mysql.connector>
</properties>

<build>

<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${version.mysql.connector}</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost/</url>
<username>xyz</username>
<password>xyz</password>
</configuration>

<executions>
<execution>
<id>drop-and-recreate-db</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>
${project.build.directory}/sql/schema/user.sql
</srcFile>
<srcFile>
${project.build.directory}/sql/schema/core.sql
</srcFile>
<srcFile>
${project.build.directory}/sql/schema/game.sql
</srcFile>
</srcFiles>
<onError>abort</onError>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>

</build>
</project>


Here we use the sql-maven-plugin to setup the database before tests are being run. The sql-maven-plugin will execute a bunch of *.sql files which are stored in a subfolder in the parent project. As you deploy the parent project to your repository, these files won't be published along with the pom.xml as the packaging is set to pom-packaging. Therefore, if you run the inherited sql-maven-plugin the *.sql files will not be available and the plugin will fail. This will certainly be a problem if your continuous integration server has a build plan for each Maven child module and not a single build plan for the entire project.

To overcome this problem, there are 2 things you have to do. First, the parent project needs to publish the *.sql files (or other static files which are needed) to your repository, so that the inheriting modules have access to these files. For this to work, we use the maven-assembly-plugin like this:


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

... as before ...

<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<inherited>false</inherited>
<configuration>
<descriptors>
<descriptor>
${project.basedir}/assembly/zip.xml
</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

<pluginManagement>
... as before ...
</pluginManagement>

</build>
</project>


Note that the maven-assembly-plugin in this case is not configured within the pluginManagement section of the parent pom, as we don't want to make this functionality available to child modules. In the configuration you can see that the plugin is set up to be executed during the package phase and that the plugin configuration is defined in the zip.xml file. This zip.xml file looks like this:


<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>sql-files</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/sql/schema</directory>
<outputDirectory/>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>


This configuration will create a zip-file of all *.sql files found in ${project.basedir}/sql/schema and publish this zip-file along with the pom.xml when mvn deploy is executed. The id of this configuration is "sql-files". This id will be used as a suffix and become part of the filename of the zip-file.

Now that we publish the zip-file to the repository, we need a way for the child modules to grab and extract the zip-file before the maven-sql-plugin is executed. This is where the maven-dependency-plugin comes in handy. Again, the maven-dependency-plugin is configured in the pluginManagement section of the parent pom.xml, as this time we want to inherit the functionality to child modules. Here is what the configuration of the maven-dependency-plugin looks like:


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

... as before ...

<build>
<plugins>
... as before ...
</plugins>

<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>unpack-sql-files</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.package</groupId>
<artifactId>project-parent</artifactId>
<version>
${parent.version}
</version>
<type>zip</type>
<classifier>sql-files</classifier>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/sql/schema
</outputDirectory>
<includes>**/*.sql</includes>
</artifactItem>
</artifactItems>
<includes>**/*</includes>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>

... as before ...

</pluginManagement>

</build>
</project>


The plugin (if a child module decides to use this) will be executed during the process-test-resources phase of the build. We are getting the zip file by specifying the groupId, artifactId, version and the type. Also the classifier value must match the id which we used earlier in the zip.xml file for configuring the maven-assembly-plugin. The zip-file is extracted to ${project.build.directory}/sql/schema and we are only extracting files having the *.sql extension (well there shouldn't be any other files but ok). This concludes what needs to be done to extract the zip-file and child modules are now ready to use the extracted files. Here is a snippet from a pom.xml file in a Maven child module. This is everything needed to run the sql-maven-plugin defined in the parent pom and extract the required configuration files upfront.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.package</groupId>
<artifactId>project-parent</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>

<artifactId>child-a</artifactId>
<packaging>war</packaging>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>


For the sake of completeness, once again the full parent pom.xml file.


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.package</groupId>
<artifactId>project-parent</artifactId>
<packaging>pom</packaging>
<version>0.1-SNAPSHOT</version>

<modules>
<module>child-a</module>
<module>child-b</module>
<module>child-c</module>
</modules>

<properties>
<version.mysql.connector>5.1.12</version.mysql.connector>
</properties>

<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<inherited>false</inherited>
<configuration>
<descriptors>
<descriptor>
${project.basedir}/assembly/zip.xml
</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>unpack-sql-files</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.package</groupId>
<artifactId>project-parent</artifactId>
<version>
${parent.version}
</version>
<type>zip</type>
<classifier>sql-files</classifier>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/sql/schema
</outputDirectory>
<includes>**/*.sql</includes>
</artifactItem>
</artifactItems>
<includes>**/*</includes>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${version.mysql.connector}</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost/</url>
<username>xyz</username>
<password>xyz</password>
</configuration>

<executions>
<execution>
<id>drop-and-recreate-db</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>
${project.build.directory}/sql/schema/user.sql
</srcFile>
<srcFile>
${project.build.directory}/sql/schema/core.sql
</srcFile>
<srcFile>
${project.build.directory}/sql/schema/game.sql
</srcFile>
</srcFiles>
<onError>abort</onError>
</configuration>
</execution>
</executions>
</plugin>
</pluginManagement>

</build>
</project>

Heating up the Code Generator

It has been a couple of years since I used a code generator in one of my projects. It must have been 2004 or 2005, when MDA was a big buzzword. Back then, we used a self-made code generator, which was written by a very smart developer who I used to work with at Aperto AG in Berlin. He even contributed the code generator to the open source community later on. Those were the days.

Since then, there wasn't much use for a code generator anymore. IDE's getting better and better at helping you with code generation and auto-completion etc. And of course, adding a generator to your build process is always a bit of work. So it is often faster to write the boilerplate code yourself, if that doesn't takes forever. However, last week it was time to bring code generation back from the grave. The game we are currently developing for EA here in Norway, has a mechanism where the game client sends game events to the server. In our domain we call these events also audit changes. A typical audit change can be that the player has found a treasure, that the player has consumed food or that the player has discovered a new scenery. On the client side, the audit change is implemented in ActionScript 3. On the server side the audit change is implemented in Java. There is a transport layer in between which serializes the AS3 object, sends it over the network and deserializes it back into a Java object. For us server developers, this meant that every new audit change also needed a transport definition about how to serialize and deserialize the audit change. This definition was always wrapped into a new audit change type class. The type definition class was written manually, which sort of was okay until we had more than 20 audit changes in the game. Thats when I started to look into generating the transport layer on the server side.

In Java 5 along with the new Annotation language feature, Sun added a command-line utility called Annotation Processing Tool (apt). This was later merged into the standard javac compiler with the release of Java 6. There is also the apt-jelly project which provides an interface to apt and can be used to generate code artifacts based on templates written with Freemarker or Jelly. Finally to glue everything together, there is the maven-apt-plugin which can be used to execute a AnnotationProcessorFactory during your build and therefore integrate apt into your project. The maven-apt-plugin looks sort of dead however. I think nowadays even the standard maven-compiler-plugin or the maven-annotation-plugin can be used to process your annotations and generate code artifacts. Since I got our generator working using the maven-apt-plugin, I did not bother looking at the other 2 plugins. If someone has a working example on how they are used with a AnnotationProcessorFactory, I would be really happy to see it. Let's look into some code now.

Here is an example of an audit change as it could exist in the game:



/**
* Audit change telling that the {@link User} has bought a {@link House}.
*/
@DatatypeDefinition(minSize = 7)
public class BoughtHouseForGold implements AuditChange {

private int itemId;

@DatatypeCollection(elementType = Integer.class)
private List<Integer> sceneries;

@DatatypeIgnore
private User friend;

... other stuff not relevant ...
}


The transport class that we want to generate need to serialize and deserialize every field of the audit change. As you can guess from above, we do not want to transport the friend field in the example. The meta data, that isn't accessible via reflection within the template which we will write later, needs to be given to the generator in another way - for instance via Annotations. Thats why I created a bunch of Annotations just to instruct the generator.


/**
* Marks the type annotated by this annotation as something that can be
* serialized and deserialized using a Datatype.
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface DatatypeDefinition {
int minSize() default 0;
}


/**
* Any {@link Field} annotated this way, will be rendered as a Collection of the
* specified type when the Datatype is generated.
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD})
public @interface DatatypeCollection {
Class<?> elementType();
}


/**
* Any {@link Field} annotated this way, will be ignored in when the Datatype is generated.
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD})
public @interface DatatypeIgnore {
}


Now for the hardest part, the template. I can recommend, that you start writing the code for the first class (the one that should be generated later) manually before you work on the template. Add the class into the default location in Maven, i.e. src/main/java/com/whatever/package. The generated classes will end up in a different location later (under target/generated-sources/) so it will be easy to compare the expected outcome and the generated outcome while working on the template. Here is a template example in which I use Freemarker directives.


<#-- for each type annotated with DatatypeDefinition -->
<@forAllTypes var="type" annotationVar="datatypeDefinition" annotation="package.DatatypeDefinition">
<#-- tell apt-jelly that the outcome will be a java source artifact -->
<@javaSource name="package.types.${type.simpleName}Type">
package package.types;

<#-- all imports go here -->
import java.io.IOException;

/**
* This class contains the {@link Datatype} for {@link ${type.simpleName}}.
*/
public class ${type.simpleName}Type extends AbstractAuditableType<${type.simpleName}> { <#-- class name based on type that was annotated with DatatypeDefinition -->
public ${type.simpleName}Type() {
super(
<#-- replace camel case with underscores -->
TypeCodes.${type.simpleName?replace("(?<=[a-z0-9])[A-Z]|(?<=[a-zA-Z])[0-9]|(?<=[A-Z])[A-Z](?=[a-z])", "_$0", 'r')?upper_case}_TYPE_CODE,
new Datatype<${type.simpleName}>(${type.simpleName}.class, ${datatypeDefinition.minSize}) {

@Override
public ${type.simpleName} read(final DatatypeInput in) throws DataFormatException {
final ${type.simpleName} value = new ${type.simpleName}();
<@forAllFields var="field">
<#assign useField = true>
<#-- do not do anything if field is a constant -->
<#if field.static = true><#assign useField = false></#if>
<#-- do not do anything if annotated with @DatatypeIgnore -->
<@ifHasAnnotation declaration=field annotation="package.DatatypeIgnore"><#assign useField = false></@ifHasAnnotation>
<#if useField = true>
<#-- build name of the setter method -->
<#assign setter = "set${field?cap_first}">
<#assign useCollection = false>
<@ifHasAnnotation var="datatypeCollectionAnnotation" declaration=field annotation="package.DatatypeCollection"><#assign useCollection = true></@ifHasAnnotation>
<#if useCollection = true>
<#if datatypeCollectionAnnotation.elementType = "java.lang.Integer">
value.${setter}(in.readList(Datatype.uintvar31));
<#else>
System.out.println('Cannot read collections of type: ${datatypeCollectionAnnotation.elementType}. Extend auditable-type.fmt');
</#if>
<#else>
<#-- Handling for fields without extra annotations -->
<#if field.type = "int" || field.type = "java.lang.Integer">
value.${setter}(in.readUintvar31());
<#elseif field.type = "boolean" || field.type = "java.lang.Boolean">
value.${setter}(in.readBoolean());
<#elseif field.type = "java.lang.String">
value.${setter}(in.readString());
</#if>
</#if>
<#assign useCollection = false>
</#if>
<#assign useField = false>
</@forAllFields>
return value;
}

@Override
public void write(final DatatypeOutput out, final ${type.simpleName} value) throws IOException {
<@forAllFields var="field">
<#assign useField = true>
<#-- do not do anything if field is a constant -->
<#if field.static = true><#assign useField = false></#if>
<#-- do not do anything if annotated with @DatatypeIgnore -->
<@ifHasAnnotation declaration=field annotation="DatatypeIgnore"><#assign useField = false></@ifHasAnnotation>
<#if useField>
<#-- build name of the getter method -->
<#assign getter = "get${field?cap_first}">
<#if field.type = "boolean" || field.type = "java.lang.Boolean">
<#-- boolean getter starts with is -->
<#assign getter = "is${field?cap_first}">
</#if>
<#assign useCollection = false>
<@ifHasAnnotation var="datatypeCollectionAnnotation" declaration=field annotation="DatatypeCollection"><#assign useCollection = true></@ifHasAnnotation>
<#if useCollection = true>
<#if datatypeCollectionAnnotation.elementType = "java.lang.Integer">
out.writeCollection(Datatype.uintvar31, value.${getter}());
<#else>
System.out.println('Cannot write collections of type: ${datatypeCollectionAnnotation.elementType}. Extend auditable-type.fmt');
</#if>
<#else>
<#if field.type = "int" || field.type = "java.lang.Integer">
out.writeUintvar31(value.${getter}());
<#elseif field.type = "boolean" || field.type = "java.lang.Boolean">
out.writeBoolean(value.${getter}());
<#elseif field.type = "java.lang.String">
out.writeString(value.${getter}());
</#if>
</#if>
<#assign useCollection = false>
</#if>
<#assign useField = false>
</@forAllFields>
}
}
);
}
}
</@javaSource>
</@forAllTypes>


My apologies, this is incredibly hard to read here on the blog. It helps to click the "view source" button in the upper right corner of the code above and copy everything to a text editor. I also added comments in the template to explain what I am doing.

Finally here is the configuration for the maven-apt-plugin, so that it will generate your code artifacts before compiling your project (note that target/generated-sources will be merged with the real sources during compile time).


<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0-alpha-4</version>
<configuration>
<factory>net.sf.jelly.apt.freemarker.FreemarkerProcessorFactory</factory>
<options>
<option>template=${basedir}/src/main/resources/apt/auditable-type.fmt
</option>
</options>
<fork>true</fork>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.apt-jelly</groupId>
<artifactId>apt-jelly-core</artifactId>
<version>2.14</version>
</dependency>
<dependency>
<groupId>net.sf.apt-jelly</groupId>
<artifactId>apt-jelly-freemarker</artifactId>
<version>2.14</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>


And voilà, here is our generated BoughtHouseForGoldType class fresh out of the oven:


package package.types;

import java.io.IOException;

/**
* This class contains the {@link Datatype} for {@link BoughtHouseForGold}.
*/
public class BoughtHouseForGoldType extends AbstractAuditableType<BoughtHouseForGold> {
public BoughtHouseForGoldType() {
super(
TypeCodes.BOUGHT_HOUSE_FOR_GOLD_TYPE_CODE,
new Datatype<BoughtHouseForGold>(BoughtHouseForGold.class, 7) {

@Override
public BoughtHouseForGold read(final DatatypeInput in) throws DataFormatException {
final BoughtHouseForGold value = new BoughtHouseForGold();
value.setItemId(in.readUintvar31());
value.setSceneries(in.readList(Datatype.uintvar31));
return value;
}

@Override
public void write(final DatatypeOutput out, final BoughtHouseForGold value) throws IOException {
out.writeUintvar31(value.getItemId());
out.writeCollection(Datatype.uintvar31, value.getSceneries());
}
}
);
}
}

The Beauties and Pitfalls of ThreadLocals

ThreadLocal must be one of the Java features, which not many developers have used. It doesn't happen so often, that you stand in front of a problem, for which ThreadLocal is the best solution. In the current game I am developing, I have however decided to use a ThreadLocal to store per-thread slash per-request context information. Actually this is one of the use cases that Brian Goetz wrote about in his great article about ThreadLocals.

Other applications for ThreadLocal include storing or accumulating per-thread context information for later retrieval.


This game uses the Spring Framework and the Servlet which is handling all requests, is a Spring Bean. When the request comes in, the Servlet will delegate handling of the request data to something that we call a RpcHandler. Once the appropriate RpcHandler is selected by the Servlet, the request has to go through 3 stages and each stage is mapped to a method in the RpcHandler.


// stage 1
public void readRequest(final DatatypeInput in) {

}

// stage 2
public void performOperation() {

}

// stage 3
public void writeResponse(final DatatypeOutput out) {

}


First the request data is read, then the RpcHandler is performing it's main operation and finally some response data might be written. In other games developers have decided to create a new instance of the RpcHandler subclass for each request. This makes it easy as the per-request context information can be stored in private fields of the RpcHandler. The negative part is that this approach is using more memory as there will be 1 instance of RpcHandler per request. This might sound acceptable if the RpcHandler was simple and lightweight but often they contain further object-trees. Because our game was Spring based, I was striving for a solution were we only had 1 instance per RpcHandler sublass. Each instance is injected as a Spring Bean into the Servlet. Since the RpcHandler interface could not be changed, so that per-request context information was given as a parameter to the 3 methods above, I needed to use a ThreadLocal.

First I create a wrapper class for the context information called Message. The RpcHandler would then contain a private field of type ThreadLocal encapsulating a Message on a per-request basis. Even though ServletContainers like Jetty or Tomcat use a thread pool were Threads are recycled, this would still be okay as one Thread is used to service an entire request (actually this might be different in Servlet 3.0 where requests can be suspended and I'am assuming Threads are given back to the pool?). Quoting Brian Goetz:

ThreadLocal is also useful in servlet-based applications or any multithreaded server application in which the unit of work is an entire request, because then a single thread will be used during the entire course of handling the request.


Since usually each Spring Bean does only exist as 1 instance per ApplicationContext (unless specified otherwise), I decided to have a non-static ThreadLocal field which is sort of different from what the JavaDoc class comment suggests:

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.


Here is an example of a typical RpcHandler subclass in the game:


public class SaveChangesHandler extends AbstractRpcHandler {

@Override
public void readRequest(final DatatypeInput in) {
// extract Message from DatatypeInput
setMessage(...);
}

@Override
public void performOperation() throws DAOException, RpcFailureException {
final Message message = getMessage();
// use Message to update the User
userService.save(message.getUser(), ...);
}

@Override
public void writeResponse(final DatatypeOutput out) throws IOException {
final Message message = getMessage();
// use Message to write something back to repsonse
out.write(message.getUser(), ...)
}

}


The AbstractRpcHandler class looks like this:


public abstract class AbstractRpcHandler extends RpcHandler<GameDaoSupport> {

private ThreadLocal<Message> threadLocalMessage;

public Message getMessage() {
return threadLocalMessage.get();
}

public void setMessage(final Message message) {
this.threadLocalMessage = new ThreadLocal<Message>();
this.threadLocalMessage.set(message);

// add a cleanup callback which will be
// executed from the ServletRequestCleanupFilter
ServletRequestCleanupService.addCleanupCallback(
new ServletRequestThreadLocalCleanupCallback(
this.threadLocalMessage
)
);
}
}


This worked well for some time but sometimes I could see the following errors in the logs:


2011-07-26 13:50:50 ERROR c.p.s.RpcServlet:handleRequest threw exception:
java.lang.NullPointerException: null
at com.foo.save.SaveChangesHandler.writeResponse(SaveChangesHandler.java:21)


Apparently the Message in writeResponse(..) was null, which was a bit strange because it was not null when performOperation(..) was invoked by the RpcServlet in stage 2. It took a bit but I found at least one problem with the code in AbstractRpcHandler:


public void setMessage(final Message message) {
this.threadLocalMessage = new ThreadLocal<Message>();
this.threadLocalMessage.set(message);

// add a cleanup callback which will be
// executed from the ServletRequestCleanupFilter
ServletRequestCleanupService.addCleanupCallback(
new ServletRequestThreadLocalCleanupCallback(
this.threadLocalMessage
)
);
}


The intention was to update the thread-local Message for the current Thread. Instead the code was reassigning the shared field to a new ThreadLocal instance and the previously assigned ThreadLocal instance was probably garbage collected. Here is a visualization of the problem flow:


Thread1 → setMessage(m1)
assigning new ThreadLocal1
ThreadLocal1.set(m1)
Thread1 → getMessage
ThreadLocal1.get → m1
Thread2 → setMessage(m2)
assigning new ThreadLocal2
ThreadLocal2.set(m2)
Thread1 → getMessage
ThreadLocal2.get → null *bang*


Took a while to spot the problem. I can really recommend to mark you static or non-static ThreadLocals as final, so this problem could not have occurred. I changed the AbstractRpcHandler to the following code and the errors disappeared.


public abstract class AbstractRpcHandler extends RpcHandler<GameDaoSupport> {

private final ThreadLocal<Message> threadLocalMessage = new ThreadLocal<Message>();

public Message getMessage() {
return threadLocalMessage.get();
}

public void setMessage(final Message message) {
this.threadLocalMessage.set(message);

// add a cleanup callback which will be
// executed from the ServletRequestCleanupFilter
ServletRequestCleanupService.addCleanupCallback(
new ServletRequestThreadLocalCleanupCallback(
this.threadLocalMessage
)
);
}
}


On a side note, I found it was a good practice to cleanup the ThreadLocals after the request was finished. Not really because this represented a memory problem as the number of Threads was limited by the Jetty thread pool. Rather I felt safer, if the recycled Thread serving a new Request would not see the Message of the previously handled HTTP Request. To do the cleanup using a Servlet Filter, I stole some code from the Apache Jetspeed 2 project (ServletRequestCleanupFilter, ServletRequestCleanupService, ServletRequestThreadLocalCleanupCallback and ServletRequestCleanupCallback).

Interviewed at Google Pt.2

Some people asked me why I wasn't publishing the second part of my Google interview experience. Well I didn't care so much about Google and job interviews in general after I moved to Norway. Anyway, I finished the whole blog post back in September at the airport in Zürich. So you might as well read the rest.

So lunch was great. Google has his own canteen with dedicated cooking staff etc. There is a salad bar, free drinks, desert and 3 dishes to choose from every day. Not bad. The canteen was packed when we went. It must have been 200 people or so.

Anyway, after lunch the next interview was again with two people, of which one was talking and the other one listening. This time I had two coding exercises in the interview. The first one, was to come up with an implementation of a class, which you could send a function or a block of executable code to, that should then be executed after 34 seconds. The second exercise was to suggest a unit test for a function producing random floats values between 0 and 1. For the first task I picked Java as concrete language and suggested using a ThreadPoolExecutor, Callable and Thread.sleep. The interviewer asked me, how we could bring down the test execution time, as we did not want to wait 34 seconds every time the test runs. I suggested having the time span configurable, so that it would fire after the configured amount of seconds. A better answer would have been to refactor the code, so that it was given an instance of a class representing a clock. I knew the clock test pattern but I was not able to pull it out in this situation - too bad. As for second task, testing random float values, I suggested creating a test set and group/count the values using some array indices. The test validation should only allow a certain degree of deviation. The interviewer then asked me how to calculate the deviation based on the input size but it was out of my league and I could not answer. For the correct answer you need some good knowledge in statistics I suppose. This was probably the worst interview I gave this day. It was also a bit harder for me because the interviewer had a very strong French accent. I had to ask him to repeat a couple of times, which might have been annoying for him. This is particular maddening because a co-worker I worked with for 3 years was French, so I should have been used to French-English.

The next interviewer was from Poland. He was a very cool guy and very friendly. We talked a bit about Apache Cassandra, which I had mentioned in my CV, since he knew one of the Facebook developers working with Cassandra. The coding exercise he had for me was about a graph problem. He gave me a class data-structure holding a list of File objects. The Files were supposed to have references to each other, pretty much like edges in a graph. I was given the task to print out the Files in a specific order. Unfortunately I understood him wrong and suggested a standard DFS traversal. But he was interested in a very specific order, which required a modified DFS approach. It was a nice interview anyways and he told me I was actually the first guy who had implemented a DFS using a stack and that he liked it. Well, I thought using a Stack for DFS was the default way, strange.

Time went by and after 45 minutes I found myself again in a very test-orientated session. The first 20 minutes or so, I was asked a lot of test related questions like "How would you do performance testing and let the development team know about the results?". My gut feeling was that I didn't give very great answers to these questions. Basically in my previous companies we never had an organization, where there was a unit of Software test engineers supporting the main developers. It is often the developer itself who does the performance testing and has the results at hand.. At least at this point, I realized I should have prepared myself more for test related questions since this was a Software Engineer in Test position after all. In my preparations I spent most time focusing on solving technical questions. But okay you never know this in advance. The final coding exercise in this interview was to come up with a suggestion on how to verify a file backup (directory structure) so that it matches a given source directory. I suggested to create an abstraction for each physical file or directory which would store the filename and a checksum. Then you could do a traversal of each tree, building up two linked lists. Finally you start removing the first item in each list and compare the items. If they don't match, it is either the directory structure that was wrong or something with the files. As the last step, I had to implement this in a language of my choice. I used again Java.

After a long day, the final interview started. A very nice girl, who worked with the Google search as a Software engineer, started to ask questions about my current job position. Surprise, this was actually the only time someone showed interest in what I was currently doing. I spoke about our system, the problems which we had and have. She asked me questions like "What happens if the database fails in this case?" and so on. I think she was testing my overall understanding of how different parts of a software system affect each other. The second part of the interview was performed as a code review. She had printed a function in Java and I my task was to review it. It was easy enough to find most of the potential issues like using static members (testability), not validating input, thread safety, going over the index bound of an array etc. I mixed up the explanation for bitwise XOR with AND, embarrassing but hey you are nervous. After doing the code review I had to rewrite a recursive function call into a iterative one, which I somehow managed. When the time was up, we said goodbye and she guided me out of the Zürich office building.

So what do I think about the interview? I think it was a great experience. I met nice people and they showed me some of my weaknesses. The preparations I had done upfront helped me only to some extend. There were less technical questions, no behavioral questions and definitely no questions about me or Google's history. A better preparation would have been to read some books on Software testing and less books about algorithms and data-structures.

So much for the second part. Here is something I am adding to the text I wrote 9 months ago. Never add technologies to your CV which you only know superficial. This can get you into embarrassing situations. Less is more. I have seen CV's for candidates who have worked with everything that exists out there - not good. For a Google interview, I think it is a plus if you know more than one language. Back then I was a Java only guy more or less. It's great if you can Python, C or C++. Some of my whiteboard examples where too Java specific, i.e. when using something like ThreadPoolExecutor take a step back and talk more about concepts than JDK classes. Don't expect every interviewer to know the language you are good at. Finally, expect to be disappointed if you fail. This can hit you hard, especially if you are used to getting a job offer every time you been to an interview.

Fluent Flexunit tests

As some of you might know, I work for a company which is doing Facebook games. Currently almost all of our Facebook games use Adobe Flash a the client and Java as the backend technology. There are different ways to have a Flex client communicate with a Java server application. For instance BlazeDS, which I really like. Unfortunately we are not using BlazeDS for the games I have been involved with. Instead we are using a framework, also based on a binary format similar to AMF, that someone at my company has written some time ago. There are some things about this framework which I don't like but overall it is performing really good. Anyway, last weekend I started to read a great book called Flex on Java, which was published by Manning almost half a year ago.

I am not the best Action Script developer, in fact I had never written a single line of Action Script when I started at my current company. The language is quite similar to JavaScript however, so Java developers are able to learn Action Script rather fast. From the first chapters in the book I could learn some stuff about Flex that I didn't knew before. Also it woke my interest in asynchronous testing using Flexunit. Similar to the Webservice example from the book, our unit-tests are also using asynchronous service calls. Well these tests are not really unit but integration tests. The first thing that is done is to start a embedded jetty using Maven and the maven-jetty-plugin:


<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<contextPath>/</contextPath>
<webApp>
${settings.localRepository}/package/goes/here/1.0-SNAPSHOT/game-1.0-SNAPSHOT.war
</webApp>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>process-test-classes</phase>
<goals>
<goal>deploy-war</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stopconfigurationReport-jetty</id>
<phase>prepare-package</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>


It is a bit dirty that we are starting a WAR file straight out of the Maven repository using an absolute file path. Not sure there is a way to tell the maven-jetty-plugin to start a WAR file of a Maven dependency instead. This does the job for now.

When embedded Jetty is running, our Flexunit integration tests will fire a sequence of service calls against the server. The sequence starts with resetting the test user, then some calls altering the player data and finally a call to load the test user back from the server. For the test user loaded at the end of the test, we run some Flexunit assert statements to validate that we are in the expected state. Since each of the service calls in the test sequence must be fired asynchronously, we use Async.handleEvent to wait until a certain Event has occurred otherwise we fail the test. Async.handleEvent has a Function argument called eventHandler, which will be the Function that is invoked if the Event has been fired successfully. Given that your service call sequence has a few steps, the test quickly mutates into a chain of Function calls of private Functions within the same test class. If you are coming from a JUnit or TestNG background, these sort of tests are not very attractive. For another developer, just from reading the code, it might be really hard to follow the test flow. I found myself adding comments all over the place, documenting where the test is continuing and what we were testing.

Here is a typical test which I made up to give you an example:


public class AlterPlayerTest {

private static const TIMEOUT : int = 2000;

private static const INITIALIZED : String = "initialized";
private static const SAVED : String = "saved";
private static const LOADED : String = "loaded";
private static const FAILED : String = "failed";

private var eventDispatcher : EventDispatcher = new EventDispatcher();
private var rpcClient : RpcClient;
private var user : User = null;

public function AlterPlayerTest() { }

[Test(async)]
public function testAlteringUser() : void {
this.rpcClient = new RpcClient(ConnectionParameters.getValues());

// make sure the user is created on the server side
this.rpcClient.init(dispatchInitializeEvent, dispatchFailEvent);
Async.handleEvent(this, this.eventDispatcher, INITIALIZED, alterUser, TIMEOUT); // flow continues in alterUser function
}

private function alterUser(evt : Event, passThru : Object) : void {
var user : User = new User();
user.id = new NetworkId(NetworkId.FACEBOOK, "189891015686187");

// make sure all objects are gone
var removeAll : RemoveAllObjects = new RemoveAllObjects();

var changeBatch : ChangeBatch = new ChangeBatch(new ArrayCollection([ removeAll ]).source);

this.rpcClient.saveUserUsingChangeBatch(dispatchSavedEvent, dispatchFailEvent, user, changeBatch);
Async.handleEvent(this, this.eventDispatcher, SAVED, reloadChangedUser, TIMEOUT); // flow continues in the reloadChangedUser function
}

private function reloadChangedUser(evt : Event, passThru : Object) : void {
// load back the user and verify that the RemoveAllObjects has been applied
this.rpcClient.load(dispatchUserLoadedEvent, dispatchFailEvent);
Async.handleEvent(this, this, LOADED, assertChanges, TIMEOUT);
}

private function assertChanges(evt : Event, passThru : Object) : void {
var user : User = this.user;
Assert.assertNotNull("user should not be null", user);

var objects : WorldObjects = this.user.worldObjects;
Assert.assertTrue("user should not have any objects left but had " + objects.length, objects.length == 0);
}

private function dispatchInitializeEvent(... args) : void {
dispatchEvent(new Event(INITIALIZED));
}

private function dispatchSavedEvent(results : Array) : void {
dispatchEvent(new Event(SAVED));
}

private function dispatchUserLoadedEvent(user : User) : void {
this.user = user;
dispatchEvent(new Event(LOADED));
}

private function dispatchFailEvent() : void {
dispatchEvent(new Event("Failed"));
}

}


In the AlterPlayerTest the service call sequence has contains only 3 service calls. The initial Flexunit test method is called testAlteringUser from which rpcClient.init is invoked. The test will break if no INITIALIZED Event is fired within 2 seconds. If the INITIALIZED Event is dispatched properly, the test flow continues with the alterUser function in which the service call rpcClient.saveUserUsingChangeBatch is made. Here the test expects the SAVED Event or it will fail. Being successful, the test will finally continue in reloadChangedUser, where the last service call rpcClient.load is made. Here the test user is retrieved from the Java server backend and again, a LOADED Event is expected. At the end the test is asserting that the test user has been altered.

While this test might be fine, we often have test scenarios where different game players interact with each other and the service call sequence is 10+ calls long, which makes the test really hard to read.

Fortunately today I found a nice framework called Fluint Sequences which has been contributed and become part of Flexunit. As the name suggests, use this if you want to write a fluent sequence of service calls within your test case. So here is a rewrite of the test above using Fluint Sequences:


public class AlterPlayerSequentiallyTest {

private static const TIMEOUT : int = 2000;

private static const INITIALIZED : String = "initialized";
private static const SAVED : String = "saved";
private static const LOADED : String = "loaded";
private static const FAILED : String = "failed";

private var eventDispatcher : EventDispatcher = new EventDispatcher();

public function AlterPlayerSequentiallyTest() { }

[Test(async)]
public function testAlteringUser() : void {
var rpcClient = new RpcClient(ConnectionParameters.getValues());

var user : User = new User();
user.id = new NetworkId(NetworkId.FACEBOOK, "189891015686187");

var passThroughData : Object = new Object();
passThroughData.usr = null;

var sequence:SequenceRunner = new SequenceRunner(this);

// make sure the user is created on the server side
sequence.addStep(sequenceCaller(rpcClient.init,
[function() : void {
eventDispatcher.dispatchEvent(new Event(INITIALIZED));
}, dispatchFailEvent]
)
);
sequence.addStep(new SequenceWaiter(this.eventDispatcher, INITIALIZED, TIMEOUT));

// make sure all objects are gone
sequence.addStep(sequenceCaller(rpcClient.saveUserUsingChangeBatch,
[function() : void {
eventDispatcher.dispatchEvent(new Event(SAVED));
}, dispatchFailEvent, user, new ChangeBatch(new ArrayCollection([ new RemoveAllObjects() ]).source)]
)
);
sequence.addStep(new SequenceWaiter(this.eventDispatcher, SAVED, TIMEOUT));

// reload user and store in passThroughData
sequence.addStep(sequenceCaller(rpcClient.load,
[function(user : User) : void {
passThroughData.usr = user;
eventDispatcher.dispatchEvent(new Event(LOADED));
}, dispatchFailEvent]
)
);
sequence.addStep(new SequenceWaiter(this.eventDispatcher, LOADED, TIMEOUT));

// assert changes
sequence.addAssertHandler(assertChanges, passThroughData);

// start the test
sequence.run();
}

private function sequenceCaller(fnc : Function, args : Array) {
return new SequenceCaller(
this.eventDispatcher,
fnc,
args
)
}

private function assertChanges(evt : Event, passThroughData : Object) : void {
var user : User = passThroughData.usr;
Assert.assertNotNull("user should not be null", user);

var objects : WorldObjects = this.user.worldObjects;
Assert.assertTrue("user should not have any objects left but had " + objects.length, objects.length == 0);
}

private function dispatchFailEvent() : void {
dispatchEvent(new Event("Failed"));
}
}


This test is not at all shorter than the first one but I think it is much easier to read and understand. Also some private member fields could be changed to local variables. The bread and butter of this test is the SequenceRunner, which acts as a container for steps which should be executed in order. No step will be executed until you invoke SequenceRunner.run() however. The first step is a SequenceCaller wrapping the rpcClient.init call followed by a SequenceWaiter step which waits the specified time for the INITIALIZED Event to occur. I do the same thing for altering and reloading the user. Finally I define and execute a Function to contain my assertions.

Bean Definition Profiles and PropertySource in Spring 3.1

Spring 3.1 is just around the corner, so it is time to have a look at what is coming. Honestly, I think there are so many changes in this releases, that I would have called this Spring 3.5 instead, but ok. The new features I am going to blog about today are Bean Definition Profiles and Property Sources.

As a Spring 1.2 dude, I have often been in a situation where you needed a Spring bean to be different based on different environments. The most common scenario is this. Lets say you are configuring your MySQL database access like this:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:app.properties</value>
</list>
</property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="${app.db.url}"/>
<property name="username" value="${app.db.username}"/>
<property name="password" value="${app.db.password}"/>
<property name="validationQuery" value="SELECT 1 FROM DUAL"/>
</bean>

</beans>


Now when running local unit test, you don't want them to mess with a real MySQL server, even though this is sort of the only way to surface these nasty MySQL integration problems. However, you want unit tests to run super fast, i.e. in memory. So what you are thinking about is something like this:


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:data"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>


A HSQLDB that runs in memory. Now there are several approaches to switch the Spring beans. What I like to do is to use the bean overriding feature. That is to create a second main file for the ApplicationContext which will re-use the first applicationContext.xml file. Lets call the second file testApplicationContext.xml. It will look like this:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<import resource="applicationContext.xml" />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:data"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>

</beans>


The bean definitions in this file will overwrite the previous bean definitions. The testApplicationContext.xml file is used like this in unit tests:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/testApplicationContext.xml")
public class SomeTest {


All good. This works well whenever you can overwrite the beans. There are alternatives. In the classpath, you could have subdirectories named after your environment, i.e. integration, production etc. Then you write some intelligent bean loader mechanism that dynamically includes the correct files. The same is possible by using <import resource="beans-${environment}.xml" />. Spring 3.1 is addressing the problem and comes with a solution in form of the so called bean definition profiles. It will allow you to do 2 new things. You can specify a profile attribute in a beans element and you are allowed to nest beans-elements, so you can have all profiles in one XML file.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:app.properties</value>
</list>
</property>
</bean>

<beans profile="testing">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:data"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
</beans>

<beans profile="production">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="${app.db.url}"/>
<property name="username" value="${app.db.username}"/>
<property name="password" value="${app.db.password}"/>
<property name="validationQuery" value="SELECT 1 FROM DUAL"/>
</bean>
</beans>
</beans>


Now you need to tell Spring which profile is active. Spring will be looking for a property called spring.profiles.active, which can be a single profile or a comma-separated list of profiles. In Spring 3.1 each ApplicationContext has a reference to a new Object which implements the new Environment Interface. This Environment instance knows all the active profiles and can therefore select the right beans out of the configuration files. To programmatically set the active profiles you would do:


final ApplicationContext applicationContext = new GenericXmlApplicationContext();

applicationContext.getEnvironment().setActiveProfiles("integration");


IntelliJ 10.5 already supports this by the way. You specify an active bean definition profile and IntelliJ will grey out the sections within the Spring configuration that are not affected by this profile - very cool. Back to the spring.profiles.active property. Spring 3.1 comes also with something new called PropertySource, which is as the name suggests a source for Properties. To identify the value for spring.profiles.active it will go through a hierarchy of property sources. The StandardEnvironment class has a PropertySource for system environment variables and JVM system properties, the latter one being more specific so it will be checked first. If you have a web application, there will also be a PropertySource for properties within the web.xml. This is done through the StandardServletEnvironment. So there are different ways to set spring.profiles.active for your application. You can have this on system level:


export spring.profiles.active=production


or start your application using:


-D spring.profiles.active=production


or have a web.xml like this:


<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</init-param>
</servlet>


These PropertySources are a really great feature. I like them even more than the bean definition profiles. I could imagine that your XML configuration can get a bit messy and hard to read if you use the profiles over excessively. I think I will stick with the bean override stuff for a while and see if the profiles are really better.

Totally unrelated and I don't remember why exactly, but recently I needed a mechanism to copy the properties for a Spring application back into System.properties when the application was loading. I think I used these properties from Spring powered beans but there were some legacy parts that were expecting them to be system properties. Here is a class that did this for me, maybe you find this useful.


import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import java.io.IOException;
import java.util.Properties;

/**
* A {@link PropertyPlaceholderConfigurer} merging loaded {@link Properties} with System {@link Properties}.
*
* Author: reik, 3/15/11
*/
public class SystemPropertiesMergingPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

/**
* Does the same as {@link PropertyPlaceholderConfigurer#mergeProperties()} but additionally merges the properties
* back into {@link System#getProperties()} before returning the loaded {@link Properties}.
*
* @return Properties
* @throws IOException
*/
@Override
protected Properties mergeProperties() throws IOException {
final Properties springProperties = super.mergeProperties();
System.getProperties().putAll(springProperties);
return springProperties;
}
}

When a design smell couldn't be more obvious

Today I was working on a small refactoring which I applied to a HttpServlet that exists in our shared codebase. This Servlet was written in a way which made it almost impossible to extend. A lot of private static methods, communicating with the database or accession filesystem resources, made this class really nice to test - ironically. In order to get anywhere, I initially decided to re-use the code by using the “copy-paste-change” pattern. A few weeks later I changed my mind and decided to make the shared code more extensible by refactoring the methods to be protected non-static. When I was done and I ran the testsuite, I saw that one test was failing.

Here is a snippet of a unit test that someone had written.


public class SomeTest {
private Method logMethod;

@BeforeMethod
public void setup() throws NoSuchMethodException {
logMethod = TheServlet.class.getDeclaredMethod(
"logEvent", new Class[] {
Parameter1.class,
Parameter2.class,
Parameter3.class}
);
}

@Test
public void testLogging() throws Exception {
logMethod.setAccessible(true);

// some set-up

logMethod.invoke(null, parameter1, parameter2, parameter3);

// asserts
}
}


Holy! I have seldom seen crappier code (and I am not even going to talk about having to catch Exception in the test method). Someone was getting a reference to the previously private static method inside the Servlet class, to be able to make it accessible via Reflection and invoke it from the test. Really, a design smell could not be more apparent. If you want to test the method, in that case it was doing some logging to the database, write a collaborator class to do the logging for you, that can be tested in isolation and is injected as a dependency. It is always good to take a step backwards and look at the million things you have to do in order to test stuff. This will most likely guide you to a better design of your software.

Continuous GUI Integration Testing

I started reading "Growing Object-Oriented Software Guided by Tests" from Steve Freeman and Nat Pryce. The book is about effectively implementing Test-Driven-Development. One of the key statements in the book, is that you should always start with a (failing) end-to-end integration test also called a "walking skeleton" before you write any code. In part III the authors give a working example in form of a Java Swing application. They use a GUI test framework called Window Licker which can automatically test Swing applications. Nat Pryce, one of the authors, drives the Window Licker project.

Since I will start to develop Facebook games for Electronic Arts in Norway in a little while, I was looking into TDD and end-to-end testing in this area. Even though I will only be responsible for server backend development, a good continuously integrated working skeleton should probably test the GUI. There are several good GUI testing frameworks like Selenium or Watir. The tests can be written like standard unit tests and run automated. However, since they make use of API integration points, it is not trivial to test Flash based applications. Selenium for instance, uses the id-attributes to interact and validate HTML elements within a web page.

I came across a really interesting new framework called Project Sikuli. This library uses image recognition to identify screen elements. Sikuli is not really meant to only support GUI testing but rather to automate every-day tasks that involve a GUI. Everything that can be seen on the screen, can be scripted, not only the web browser. I can have a Sikuli script that clicks on "System > Administration > Nvidia X Server Settings" in Ubuntu and changes my screen resolution if I wanted to. Sikuli comes with a minimalistic IDE which allows you to take snapshot of a screen region that you want to interact with. In addition to that, using the IDE you can also test how well your snapshot region is recognized on the screen. The better it is recognized, the less often your unit tests will fail. Since the project is written in Java, there is also a Java library which enables you to write unit tests using Sikuli.

Let's give a working example. I want to write a integration test, that can be run automatically using Maven. The test should login to Facebook, go to the Farmville (actually a Flash game from our biggest competitor Zynga), click on the "Gifts" icon, click on "Sell" and finally click on the "Cancel" button. I am using Sikuli 0.10.2 in this example. First step to install all required dependencies in Ubuntu. Next step to download Sikuli 0.10.2 and add it to my local Maven repository since it is not available in any official Maven repository yet. Having Sikuli available as dependency, it is time for the first unit test.


package lantern.day.gui;

import edu.mit.csail.uid.FindFailed;
import edu.mit.csail.uid.Screen;
import org.junit.Before;
import org.junit.Test;

import java.net.URL;

/**
* Verifies selling gifts can be cancelled in Farmville using
* the Sikuli test framework.
*
* @author reiks, Jan 28, 2011
*/
public class FarmvilleCancelGiftSellingTest {

private Screen _screen;

@Before
public void setUp() {
_screen = new Screen();
}

@Test
public void openFacebookHomepage() throws FindFailed {
openChrome();
goToURL("http://www.facebook.com/");
login();
startFarmville();
cancelSellingOfGifts();
closeChrome();
}

private String fullPath(final String fileName) {
final URL url = ClassLoader.getSystemResource(fileName);
return url.getFile();
}

private void login() throws FindFailed {
_screen.type(fullPath("email.png"), "password\n", 0);
}

private void openChrome() throws FindFailed {
_screen.click(fullPath("chrome_icon.png"), 0);
_screen.wait(fullPath("new_tab.png"));
}

private void closeChrome() throws FindFailed {
_screen.click(fullPath("close.png"), 0);
}

private void goToURL(final String url) throws FindFailed {
_screen.paste(fullPath("url_bar.png"), url);
_screen.type(fullPath("url_bar.png"), "\n", 0);
}

private void startFarmville() throws FindFailed {
_screen.click(fullPath("farmville_icon.png"), 0);
_screen.wait(fullPath("gift.png"), 5000);
}

private void cancelSellingOfGifts() throws FindFailed {
_screen.click(fullPath("gift.png"), 0);
_screen.wait(fullPath("sell.png"), 1000);
_screen.click(fullPath("sell.png"), 0);
_screen.wait(fullPath("cancel.png"), 1000);
_screen.click(fullPath("cancel.png"), 0);
}
}


The FarmvilleCancelGiftSellingTest will open my local Google Chrome browser, go to http://www.facebook.com/, enter some test user credentials to log in, click the small Farmville icon to the left and so on. The test requires a couple of PNG files which Sikuli will use to identify the screen elements which it needs to click and validate. In this very simple test case, I am mainly using two methods of the edu.mit.csail.uid.Screen instance - click and wait. First I click an image then I wait for another image to be present on the screen. If the image I am waiting for is not found, the test will fail. I also use the type and paste functions in this class, to enter text into HTML text fields.

One important aspect of automated GUI integration testing, is the ability to check what went wrong if tests start to fail. Some developers have scripted their builds to take screen-shots during the test run, I decided to record the desktop as a video. An idea which I stole from the Window Licker website. Instead of using a JUnitResultFormatter, I wrote a RunListener that is being used from the maven-surefire-plugin. The code of the RunListener is almost identical to the ResultFormatter. Every test is being recorded using the Linux program recordmydesktop. If the unit test is failing, the video file is kept otherwise it is deleted. Here is the video for the FarmvilleCancelGiftSellingTest. It is running a bit fast as a video clip. During the actual test execution it is running much slower. *Update* thanks to EmbedPlus you can play the video in slow motion now. Just click the "Slow" button before you start playing the video. What you see in the video, is a Maven build starting a Chrome browser, executing and recording the test.








data="http://www.youtube.com/v/wz61YtMIWh8?fs=1">








And finally the pom.xml I am using to run the Sikuli tests from Maven.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>lantern.day</groupId>
<artifactId>gui-testing</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Automated GUI Testing using Project Sikuli</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.sikuli</groupId>
<artifactId>sikuli-script</artifactId>
<version>0.10.2</version>
</dependency>

<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-junit</artifactId>
<version>1.8.2</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<showWarnings>false</showWarnings>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>lantern.day.gui.junit.RecordingListener
</value>
</property>
</properties>
</configuration>
</plugin>

</plugins>
</build>

</project>