Java 9's javac
has a new flag --release
:
> javac --help ... --release <release> Compile for a specific VM version. Supported targets: 6, 7, 8, 9
How is it different from -source
and -target
flags? Is it just a shortcut for -source X -target X
?
The javac command reads source files that contain module, package and type declarations written in the Java programming language, and compiles them into class files that run on the Java Virtual Machine. The javac command can also process annotations in Java source files and classes.
javac compiles the code and makes it into an executable format. java runs the code you just built. Hope this helps!
The javac command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files.
Not exactly.
JEP 247: Compile for Older Platform Versions defines this new command-line option, --release
:
We defined a new command-line option,
--release
, which automatically configures the compiler to produce class files that will link against an implementation of the given platform version. For the platforms predefined injavac
,--release N
is equivalent to-source N -target N -bootclasspath <bootclasspath-from-N>
. (emphasis mine)
So no, it is not equivalent to -source N -target N
. The reason for this addition is stated in the "Motivation" section:
javac
provides two command line options,-source
and-target
, which can be used to select the version of the Java language accepted by the compiler and the version of the class files it produces, respectively. By default, however,javac
compiles against the most-recent version of the platform APIs. The compiled program can therefore accidentally use APIs only available in the current version of the platform. Such programs cannot run on older versions of the platform, regardless of the values passed to the-source
and-target
. options. This is a long-term usability pain point, since users expect that by using these options they'll get class files that can run on the specified platform version.
In short, specifying the source and target options are not sufficient for cross-compilation. Because javac
, by default, compiles against the most recent of the platform APIs, they can't be guaranteed to run on older versions. You also need to specify the -bootclasspath
option corresponding to the older version to cross-compile correctly. This would include the correct API version to compile against and allow for execution on older version. Since it was very often forgotten, it was decided to add one command line option which did all the necessary things to correctly cross-compile.
Further reading in the mailing list and Oracle Docs. The original bug was filed here. Note that since the integration of this option, JDK builds have come bundled with descriptions of the platform APIs of older releases, mentioned under section "Risks and Assumptions". That means you don't need the older version installed on your machine for cross-compilation to work.
--release X
is more than just a shortcut to -source X -target X
because -source
and -target
are not sufficient to safely compile to an older release. You also need to set a -bootclasspath
flag which must correspond to the older release (and this flag is often forgotten). So, in Java 9 they made a single --release
flag which is a replacement for three flags: -source
, -target
and -bootclasspath
.
So, this is an example of compiling to Java 1.7:
javac --release 7 <source files>
Note that you don't even need to have JDK 7 installed on your computer. JDK 9 already contains the needed information to prevent you from accidental linking to symbols that did not exist in JDK 7.
Another important difference is that you can only use public APIs when compiling with --release
:
> javac --add-exports java.base/sun.invoke=ALL-UNNAMED --release 11 Main.java error: exporting a package from system module java.base is not allowed with --release 1 error
If you want to use internal APIs, you have to remove the option --release
:
> javac --add-exports java.base/sun.invoke=ALL-UNNAMED Main.java
or
> javac --add-exports java.base/sun.invoke=ALL-UNNAMED -source 11 -target 11 Main.java
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With