Thursday, June 25, 2009

Ant builds targetting a particular Java SDK version

I've wanted to blog some development topics for quite a while now, so here goes. Please stop reading here if you are not a programmer. No, really, you'll damage your eyes!

Ant's javac task offers handy access to Java's javac compiler options, including the seductive but deceptive -source and -target. Seductive because it allows you to easily declare and ensure that your source and the resulting classes comply with a particular version of the java language and JVM, respectively.

Deceptive because it does that and only that! A JRE or JDK contains a JVM, but also a whole lot more! I was recently caught out when working on an old project by java.lang.String.IsEmpty(), which Ant happily compiled into a JVM 1.4 compliant class, even though the method was introduced in Java 1.6.

It's obvious when you think about it, but the JVM (and its contained classes) running Ant will determine whether something like that compiles or not - there's no practical way for javac to know which methods are in which JDK. It just checks the JDK classes given to it by Ant.

So the moral of the story is, if you are targetting a particular JDK, run Ant on that JDK to build your project. You can include a version check with the fail and condition tasks before your javac task. For example:

<fail message="Use JDK 1.4 to run this Ant build">
<condition>
<not>
<matches pattern="^1[.]4.*$" string="${java.version}"/>
</not>
</condition>
</fail>

4 comments:

Dimitar said...

Or (a bit easier) use the bootclasspath option, pointing to the rt.jar or the JRE you are building against. That works quite well when you are ctosscompiling against 5 different mobile JREs.

sicklittlemonkey said...

Ah thanks Dimitar, that's much nicer. The Ant docs don't document bootclasspath very well, but the javac docs have a nice example.

Now why didn't the Java guru on the project know that? ... Will have to hit him up about it. ;-)

Dimitar said...

Well, it's not a common use case unless you are doing mobile development.

sicklittlemonkey said...

I approved your last comment after thinking about it for 4 years. : - /

Seriously, though, this seems useful for more than mobile. How else does one target and verify an older runtime - safeguarded by compile-time errors?