Skip to main content

Testing JDK 1.4 production code using Java 5 tests in Maven

Posted by johnsmart on August 2, 2010 at 7:13 AM PDT

Java 5 marks a huge step forward in the realm of automated testing. JUnit 4, for example, introduces many powerful new features based on annotations, such as flexible test names and parameterized testing. TestNG has had very cool annotation-based features since its first release. And Selenium 2.0/WebDriver also has some great new features based on annotations that make it much easier to create Page Objects.

However there are still those of us who, usually for reasons beyond our control, need to deploy to a Java 1.4-based environment. So are you stuck with prehistoric unit testing tools and prehistoric testing practices? The answer is no - even deploying to an archaic JVM, you can still use these new features for your tests. Curious? Read on!


In fact, it's not too difficult, once you know how. The first thing you need to do is to configure the compiler options for each phase, to ensure that your application source code is compiled for Java 1.4, and your test code for Java 1.5. This isn't too hard: you can do it by configuring the maven-compiler-plugin as shown here:


<project...>
  <build>
    ...
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.1</version>
    <executions>
      <execution>
        <id>java-1.4-compile</id>
        <phase>compile</phase>
        <goals>
          <goal>compile</goal>
        </goals>
        <configuration>
          <source>1.4</source>
          <target>1.4</target>
        </configuration>
      </execution>
      <execution>
        <id>java-1.5-compile</id>
        <phase>process-test-sources</phase>
        <goals>
          <goal>testCompile</goal>
        </goals>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </execution>
    </executions>
  </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

This will ensure that your application code will fail to compile if any generics, enumerations or other Java 5 features slip in, but still allow you to use all of these features in your test code.

This is great, but we're not done yet. There are still some more subtle dangers. For example, the String class introduced the contains() method in Java 5. However, with the above configuration, if you use this method your code will still compile, but it won't run in a Java 1.4 environment.

The answer comes in the form of the somewhat strangely named animal-sniffer-maven-plugin. The Animal Sniffer Plugin lets you check your code against the signature of a given API, and in particular against the API of specific versions of the JDK. If you want to ensure that your code works against Java 1.4, you just need to add the following plugin configuration to your build section:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>animal-sniffer-maven-plugin</artifactId>
  <version>1.6</version>
  <configuration>
    <signature>
      <groupId>org.codehaus.mojo.signature</groupId>
      <artifactId>java14</artifactId>
      <version>1.0</version>
    </signature>
  </configuration>
  <executions>
    <execution>
      <phase>test</phase>
      <goals>
        <goal>check</goal>
      </goals>
    </execution>
  </executions>
</plugin>

The animal-sniffer-maven-plugin accepts values like java13, java14, java15 or java16. You can also be more precise if required - for example, java15-sun or java14-ibm.

So, if you want to try the new and cool annotation-based features of many modern automated testing frameworks, but still need to deploy to an antediluvian JVM in production, now you can!

If you want to learn more cool Maven build automation tricks and funky automated testing practices, be sure to check out the upcoming Java Power Tools Bootcamps, coming soon to Wellington, London and Canberra.

Related Topics >>