javac so that it can compile Java programs to run on selected
older versions of the platform.
javac provides two command line options,
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
-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 the platform version specified
A new command-line option,
--release, is defined, which
automatically configures the compiler to produce class files that will
link against an implementation of the given platform version.
--release N is
roughly equivalent to:
- for N < 9:
-source N -target N -bootclasspath <documented-APIs-from-N>,
- for N >= 9:
-source N -target N --system <documented-APIs-from-N>.
For N < 9, the documented APIs consist of the public APIs that were on javac's default bootclasspath for JDK N.
For N >= 9, the documented APIs consist of (i) the APIs exported from those modules in the JDK image which are part of the documentation of JDK N; and (ii) the API exported from the jdk.unsupported module (documented in JEP 260). That is, the documented APIs are primarily the APIs exported by the intersection of the modules in the JDK image and the modules documented for JDK N. No other modules in the JDK image are observable. If --limit-modules is used, then it can only further limit the observable modules, not observe additional modules. Access to internals of the modules in the JDK image is not allowed.
--release N option is incompatible with other options that affect the set of
platform or system classes. This includes:
- for N < 9:
-Djava.ext.dirsoptions that set platform classes.
- for N >= 9: the
--upgrade-module-pathoptions that set system modules (that is, modules in the JDK image), and the
--patch-moduleoptions if they modify system modules. (Use of
--patch-moduleis allowed for non-system modules, that is, modules that are not part of the JDK image.)
- for any N, the
-targetoptions, as those are automatically set to N.
It is assumed that documented APIs will change only in major releases. For the legacy case where JAX-WS was updated from 2.0 to 2.1 in a minor release of JDK 6, JAX-WS 2.1 is considered the documented API.
As a limitation of the
--release implementation, the Unicode version of
the given target platform is not used during compilation; the Unicode
version of the current platform is used instead.
For JDK N and
--release M, M < N, signature data of the documented APIs of
release M of the platform is needed. This data is stored in the
$JDK_ROOT/lib/ct.sym file, which is similar, but not the same, as the
file of the same name in JDK 8. The
ct.sym file is a ZIP file
containing stripped-down class files corresponding to class files from the
target platform versions.
For JDK N and
--release N,the JDK's own image is used as the source
of the class files to compile against. The list of observable modules is limited, however,
to the documented modules and the jdk.unsupported module.
Risks and Assumptions
The JDK source-code repository needs to contain a description of the platform APIs of past releases. The size of the description may be considerable, and the resulting JDK builds will be larger. Care has been taken to reduce these space overheads as much as possible.