Compiling for a different version of Java
suggest changeThe Java programming language (and its runtime) has undergone numerous changes since its release since its initial public release. These changes include:
- Changes in the Java programming language syntax and semantics
- Changes in the APIs provided by the Java standard class libraries.
- Changes in the Java (bytecode) instruction set and classfile format.
With very few exceptions (for example the enum
keyword, changes to some “internal” classes, etc), these changes are backwards compatible.
- A Java program that was compiled using an older version of the Java toolchain will run on a newer version Java platform without recompilation.
- A Java program that was written in an older version of Java will compile successfully with a new Java compiler.
Compiling old Java with a newer compiler
If you need to (re-)compile older Java code on a newer Java platform to run on the newer platform, you generally don’t need to give any special compilation flags. In a few cases (e.g. if you had used enum
as an identifier) you could use the -source
option to disable the new syntax. For example, given the following class:
public class OldSyntax {
private static int enum; // invalid in Java 5 or later
}
the following is required to compile the class using a Java 5 compiler (or later):
$ javac -source 1.4 OldSyntax.java
Compiling for an older execution platform
If you need to compile Java to run on an older Java platforms, the simplest approach is to install a JDK for the oldest version you need to support, and use that JDK’s compiler in your builds.
You can also compile with a newer Java compiler, but there are complicated. First of all, there some important preconditions that must be satisfied:
- The code you are compiling must not use Java language constructs that were not available in the version of Java that you are targeting.
- The code must not depend on standard Java classes, fields, methods and so on that were not available in the older platforms.
- Third party libraries that the code depends must also be built for the older platform and available at compile-time and run-time.
Given the preconditions are met, you can recompile code for an older platform using the -target
option. For example,
$ javac -target 1.4 SomeClass.java
will compile the above class to produce bytecodes that are compatible with Java 1.4 or later JVM. (In fact, the -source
option implies a compatible -target
, so javac -source 1.4 ...
would have the same effect. The relationship between -source
and -target
is described in the Oracle documentation.)
Having said that, if you simply use -target
or -source
, you will still be compiling against the standard class libraries provided by the compiler’s JDK. If you are not careful, you can end up with classes with the correct bytecode version, but with dependencies on APIs that are not available. The solution is to use the -bootclasspath
option. For example:
$ javac -target 1.4 --bootclasspath path/to/java1.4/rt.jar SomeClass.java
will compile against an alternative set of runtime libraries. If the class being compiled has (accidental) dependencies on newer libraries, this will give you compilation errors.