JEP 247: Compile for Older Platform Versions

OwnerJan Lahoda
Created2014/09/10 16:56
Updated2016/10/28 22:04
TypeFeature
StatusCompleted
Componenttools / javac
ScopeJDK
Discussioncompiler dash dev at openjdk dot java dot net
EffortM
DurationL
Priority3
Reviewed byAlex Buckley, Brian Goetz, Jonathan Gibbons
Endorsed byBrian Goetz
Release9
Issue8058150

Summary

Enhance javac so that it can compile Java programs to run on selected older versions of the platform.

Motivation

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.

Description

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 in javac, --release N is equivalent to -source N -target N -bootclasspath <bootclasspath-from-N>.

To get the bootclasspath from version N, signature data from past releases 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 classfiles corresponding to classfiles from the target platform versions. The history data currently only contain public/exported APIs of the target platforms that were on the javac's default bootclasspath.

Currently, it is not expected the covered APIs will change inside one release train. For the existing case where this happened for JDK 6 updates (update of JAX-WS from 2.0 to 2.1 in JDK 6 updates), the newer API was selected.

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.

The --release command line option is incompatible with numerous javac command line options including -source, -target, -bootclasspath, and -endorseddirs.

The set of recognized platforms is pluggable using an internal API (com.sun.tools.javac.platform.PlatformProvider). Plugged-in platform definitions are able to affect other selected javac configuration properties besides -source and -target, for example adding annotation processors or javac Plugins.

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.