Hunting API incompatibilities with the animal sniffer project

If you have been developing in the java language since at least some time ago, for sure you had been working with many Java versions: 1.4, 1.5, 1.6, …

Each new version of the java runtime environment and development kit usually provides some improvements in:

  1. The Java language (LANG changes).
  2. The Java API. (API changes).
  3. The Java virtual machine. (JVM changes).

If you use one of those improvements in your application, it will need a JRE of that version or greater to run.

That wouldn’t be a problem if everybody used always the last available java versions. However the change to newer versions is performed slowly on some corporations or offices where a specific java version is certified and supported, the change to a newer version is an IT or costs headache, or just not possible at all.

So the usual current scenario is a developer who wants its Java program to be compatible with Java 1.5 or newer, but its using the Java 1.6 (or the upcoming 1.7) version in its development tools. And that way is very easy to add a Java 1.5 incompatibility accidentally.

That is the usual scenario also for the gvSIG desktop project, so some measures had been taken to try to avoid those problems in the 2.0.0 version:

  • Configure the maven-compiler-plugin for java 1.5 source and binary compatibility. The source compatibility prevents from the usage of newer language features (LANG changes). The binary compatibility prevents to compile to a format supported only by newer JVMs (JVM changes). In gvSIG 2.0 this is achieved by configuring the maven-compiler-plugin like this:
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
                <encoding>ISO-8859-1</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>
  • Configure the eclipse java compiler compliance. This is automatically done while using the maven-eclipse-plugin to generate the eclipse projects configuration from the maven one. This prevents more or less the same incompatibilities as the previous measure.

But there is a change which is not detected by those measures: the usage of new API changes. If you use a method available only since Java 1.6, you won’t be able to detect it unless running or compiling your application with a 1.5 or older version.

That has been happening in the gvSIG project from time to time, as the developers use a Java 1.6 version, and the current gvSIG final builds are distributed with that version also. We find the problems later when someone is trying to develop or use gvSIG with a 1.5 JRE.

So how could we detect the Java API incompatibilites while developing with gvSIG?

The answer is by using the Animal sniffer project. This project provides utilities to validate Java code against an API. You can check against Java standard APIs, or even against your own ones.

It also provides a maven plugin, which we have just configured for the gvSIG 2.0 project like this:

<build>   
    <pluginManagement>
        <plugins>
            ...
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>animal-sniffer-maven-plugin</artifactId>
                <version>1.7</version>
            </plugin>
        </plugins>
     </pluginManagement>
     <plugins>
        ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>animal-sniffer-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>check-java-api</id>
                    <phase>test</phase>
                    <goals>
                        <goal>check</goal>
                    </goals>
                    <configuration>
                        <signature>
                            <groupId>org.codehaus.mojo.signature
                            </groupId>
                            <artifactId>java15</artifactId>
                            <version>1.0</version>
                        </signature>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
 </build>

So from now on, all gvSIG 2.0 official projects will have that configuration by default, and will be checked when performing a mvn test or mvn install operation. If there is an incompatibility in one of the projects, you will find in the maven log something like this:

[INFO] [animal-sniffer:check {execution: check-java-api}]
[INFO] Checking unresolved references to org.codehaus.mojo.
signature:java15:1.0
[ERROR] Undefined reference: java/lang/String.contains(Ljava/lang/
CharSequence;)Z in /home/cordin/projects/gvsig/svn/gvSIG-tools2/org.
gvsig.tools/org.gvsig.tools.lib/target/classes/org/gvsig/tools/
dynobject/impl/DefaultDynClassName.class

If you are developing a gvSIG plugin but want to change the java API version to check against to (1.4, 1.6, etc.), just add the following to your pom.xml build/plugins configuration (replace java14 with your required version):

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

About cordin

I'm the CTO of the DiSiD Technologies (http://www.disid.com) company, and also one of the gvSIG project (http://www.gvsig.org) software architects.
This entry was posted in development, english, gvSIG Desktop, gvSIG Mobile. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s