Pragmatic Programmer Issues

Maven 2.2.0 Released

New version of maven was released. One of the benefit is that there are many bug fixes and some regression from 2.1.0 was fixed.

The main issue when upgrading is that new maven requires Java 1.5 or later! If you still have system which must be build for Java 1.4 you’ve got trouble to overcome. There is guide how you can configure your pom to use ensure that you do not use API from later version t han suggested.

This is achieved by using animal-sniffer. Animal-sniffer is project which goal is to provide tools for developers which must use many different Java versions. For example I use java 1.4, java 5 and java 6 in my daily work.

Currently there are maven plugin and command line tool. Command line help us to find which class is compiled by which java version, it may help to spot libraries or modules compiled by higher version than our project.

Most helpful is maven plugin which can be configure in such way that it rise build error if we use API from higher java version. Assume the code:

package info.pietrowski;

public class Main {
    public static void main(String[] args) {
        BigDecimal d = new BigDecimal(10); // this constructor is since 1.5
        System.out.println(d);
    }
}

Now we configure maven to target for 1.4 java platform, but JAVA_HOME points to java 5 or higher

...

  maven-compiler-plugin
  
    1.4
    1.4
  

...

Running this program with different java version drive to the output

$ jdk1.6.0_13/bin/java -classpath test.jar info.pietrowski.Main
10
$ j2sdk1.4.2_16/bin/java -classpath test.jar info.pietrowski.Main
Exception in thread "main" java.lang.NoSuchMethodError: java.math.BigDecimal.(I)V
        at info.pietrowski.Main.main(Main.java:10)

The problem is that compiler choose BigDecimal constructor based on rt.jar, and despite produce bytecode 1.4 compatible, can run it because rt.jar in java 1.4 do not have this constructor.

The rescue for this problem is animal-sniffer maven plugin which we can configure like this:

...
  
    org.jvnet
    animal-sniffer
      
        
          animal-sniffer
          compile
            
              check
            
            
              
                org.jvnet.animal-sniffer
                java${jdk.level}
                1.0
              
            
          
        
      
        
          org.jvnet.animal-sniffer
          java${jdk.level}
          1.0
          sig
        
     
   
...

Where jdk.level is property for target java version. Also this two resource has some configuration guidance:
Signature Checker guideline and Guide to building 1.4 project.

Currently they have signatures for

  • java1.3
  • java1.4
  • java1.5
  • java1.6

And hopefully you do not have to use older java than 1.3.

After this change pom like suggested and try to build by java higher than 1.5 we get this error message:

[INFO] [animal-sniffer:check {execution: animal-sniffer}]
[INFO] Checking unresolved references to org.jvnet.animal-sniffer:java1.4:1.0
[ERROR] Undefined reference: java/math/BigDecimal.(I)V in ...\target\classes\info\pietrowski\Main.class
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Signature errors found. Verify them and put @IgnoreJRERequirement on them.

Thanks to Marcin who test with me this configuration and finally put this into our organization parent pom for all our developers.

Categories