Today I merged some code and soon was notified that my code broke the continuous integration:

In file FooDO I added one line to class annotation:

@NamedQueries({
@NamedQuery(name = NamedQueryConsts.Name.FOO_NAME, query = NamedQueryConsts.JPQuery.FOO_QUERY),
@NamedQuery(name = NamedQueryConsts.Name.BAR_NAME, query = NamedQueryConsts.JPQuery.BAR_QUERY), })
public abstract class FooDO extends BaseDO
I like to add a trailing comma at the end of the array because it’s legal Java, and it will help me/other developers not to worry about the missing comma  when some time later a new array item is needed to be added. As usual I run ant build to make sure everything is OK before I finally merge. And as usual I ignored the build failure notification email since I am sure my merge is all good. But soon I was told that my merge caused it… Interesting.
Error message:
[javac] /path/to/FooDO.java:76: illegal start of expression
[javac] @NamedQuery(name = NamedQueryConsts.Name.BAR_NAME, query = NamedQueryConsts.JPQuery.BAR_QUERY), })
[javac] ^
[javac] 1 error

The fix is pretty simple that I removed the trailing comma and it passed the integration build. But how they behave differently? Java version should be blame. I checked the Java version on the integration server, it’s 1.6.0_29-b11, HotSpot. My local Java is 1.6.0_22, OpenJDK, and since we deliver by JRockit I set JAVA_HOME to it, whose version is 1.6.0_37. Both OpenJDK and JRockit accepts trailing comma at the end of annotation array.

Googled the issue and I found there is JDK bug describing the same issue and it’s fixed in JDK6u30, but unfortunately the integration server is using JDK6u29 :( To avoid such unexpected build broken we have to update the build.xml file to specify the JDK so that we run ant build with the same JDK integration server uses (It’s under source control) or in our script to setup development environment, we set JAVA_HOME to the one integration server uses. It’s really frustrating that everything works at your side, but breaks elsewhere. And by the way, we may need to update the JDK under the source control.