13

I've recently moved to Java 7 in one of my projects. I claim that it can run on Java 1.5 simply because there's nothing I depend on that is in Java 6 or 7. However when compiling today I noticed this:

bootstrap class path not set in conjunction with -source 1.5

Google has found little information on this warning. Does this mean that you can't compile to Java 1.5 from Java 1.7?

TheLQ
  • 14,830
  • 14
  • 69
  • 107
  • Not sure about the error message, but I would have unit tests that automatically run against each significant (1.x) version of Java that I claim to support. – Eric J. Oct 22 '11 at 00:10

4 Answers4

13

This Oracle blog explains the warning:

http://blogs.oracle.com/darcy/entry/bootclasspath_older_source

The reason is, that if you fail to set rt.jar for the older platform, then:

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.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
12

Does this mean that you can't compile to Java 1.5 from Java 1.7?

No it doesn't. It means that there is a right way and a wrong way to do this ... and you are doing it the wrong way.

The right way to compile for the Java 1.5 on a Java 1.7 JDK is:

  • Get hold of a copy of the "rt.jar" from Java 1.5 and put it on the compilation bootclasspath.

  • Compile with -source 1.5 and -target 1.5.

The warning message is telling you that you haven't done the first of these.


The way that you are building right now is implicitly using the 1.7 version of "rt.jar" for the Java runtime APIs. This may work! (Indeed, it should work assuming that you've made no changes to the code since it last built on 1.5.) However, there is a risk that you may accidentally introduce dependencies on classes or methods added in Java 1.6 or 1.7. That would result in runtime errors when you try to run your application on Java 1.5.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
6
  1. You better be setting -source and -target 1.5.

  2. To be really sure that you aren't accidentally incorporating dependencies on newer classes, methods, or fields, use the maven-animal-sniffer plugin or something like it.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • 2
    +1 because I've never heard of maven-animal-sniffer before and wish I did many times. (University assignment test environments that haven't been updated in 10 years = argh.) – millimoose Oct 22 '11 at 00:16
  • 2
    I think it's also recommended to set `-target 1.5`. I think the classfile format version number was bumped between 1.5 and 1.6, so a 1.5 VM might be unable to load them. (Even if not, better safe than sorry.) – millimoose Oct 22 '11 at 00:19
  • if `-source` and `-target` are specified, the 1.7 compiler prompts for `-xbootclasspath` - which accounts for point 2. – Andrew Thompson Oct 22 '11 at 05:21
  • One problem that animal-sniffer-plugin exposes is that some 3rd party libraries may be using Java 6 or 7 APIs. This is an issue with Java libraries that hasn't really been brought to light, because we all just upgrade, upgrade, and upgrade. Scala and sbt does a better job of cross building different versions of libraries. – gregturn Sep 28 '12 at 16:34
2

--source 1.5 will make sure the source files comply with Java 5 conventions. --target 1.5 will make sure the generated class files comply with Java 5 conventions. Neither of these will protect you from using Java 6 or 7 library methods. You must either compile against the appropriate rt.jar using --bootclasspath, or use something like the animal-sniffer-plugin (if you are using maven) which will inspect everything's type signature, and compare with published profiles.

With the animal-sniffer-plugin, you may be in for a treat, because you can bump into 3rd party libraries that use Java 6 APIs, which may cause your build process to fail given you are pursing Java 5.

gregturn
  • 2,625
  • 3
  • 25
  • 40