Question

We have a Java project that we wish to distribute to users. It does not use any Java features beyond Java 1.5, so we wish it to run on Java 1.5 and above.

At this point, you might rightfully note that Java 1.6 is the oldest available currently, so why target Java 1.5? However, that does not change the generic nature of the question of cross-compiling for older versions.

So, the way one usually starts cross-compilation attempts is by specifying -source 1.5 and -target 1.5 options to javac, at which point one gets a famous warning about -bootclasspath not being set:

$ javac -source 1.5 -target 1.5 Test.java 
warning: [options] bootstrap class path not set in conjunction with -source 1.5
1 warning

Now, according to Oracle blog post, as well as official documentation, the correct practice for cross-compilation is to:

To use javac from JDK N to cross-compiler to an older platform version, the correct practice is to:

  • Use the older -source setting.
  • Set the bootclasspath to compile against the rt.jar (or equivalent) for the older platform.

If the second step is not taken, javac will dutifully use the old language rules combined with new libraries, which can result in class files that do not work on the older platform since references to non-existent methods can get included.

For instance, quoting official documentation:

% javac -source 1.6 -target 1.6 -bootclasspath jdk1.6.0/lib/rt.jar \
    -extdirs "" OldCode.java

This is great and has been answered many times before both on Stack Overflow and the rest of the Internet.

However, none of the resources we have found seem to indicate where to actually find the rt.jar for older versions of Java. As an example, JDK 1.7 does not ship with rt.jar except its own:

$ find jdk-1.7.0_45 -name rt.jar
jdk-1.7.0_45/jre/lib/rt.jar

That makes one think that in order to obtain rt.jar for Java 1.6, for instance, one needs to download JDK 1.6. But then two questions arise:

  1. if we download JDK 1.6, we might as well use that for compilation instead of JDK 1.7;
  2. if we wish to cross-compile for Java 1.5, then JDK 1.5 is no longer available for download.

So, how do we actually specify -bootclasspath option to use this cross-compilation feature?

Était-ce utile?

La solution 2

This type of compilation is primarily motivated by needing to target a JRE that is already in production or an otherwise existing install, IME. In that case, pulling the JRE bootclasspath files from the existing install and making them available from the build system(s) would be the first task. The bootclasspath value you specify will depend on where you put the JRE bootclasspath files during that step.

FYI, you may need quite a few more files than just rt.jar. E.g., when targeting IBM Java 6.

Autres conseils

The rt.jar is included with the JRE. You will be able to perform the cross compilation if you have, say, JDK 1.6 and JRE 1.5.

Using your JDK 1.6:

$ javac -source 1.5 -target 1.5 -bootclasspath jre1.5.0/lib/rt.jar Test.java

The advantage here is that the JRE can be as little as 1/3 the size of a full JDK. You can often remove old JDK versions without removing old JRE versions.

If you need to get hold of an old JRE, they can be found following links on the Java Archive page http://www.oracle.com/technetwork/java/javase/archive-139210.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top