JEP 322: Time-Based Release Versioning

OwnerMark Reinhold
Created2017/11/30 17:51
Updated2017/12/14 01:45
TypeFeature
StatusIntegrated
Componentcore-libs / java.lang
ScopeSE
Discussionjdk dash dev at openjdk dot java dot net
EffortM
DurationS
Priority2
Reviewed byAlan Bateman, Alex Buckley, Dalibor Topic, Iris Clark, John Rose
Endorsed byBrian Goetz
Release10
Issue8192828

Summary

Revise the version-string scheme of the Java SE Platform and the JDK, and related versioning information, for present and future time-based release models.

Goals

Non-Goals

It is not a goal to revise the existing version-string scheme to accommodate requirements other than those related to time-based release models.

It is not a goal to revise the version-report output of command-line tools other than the java launcher. Doing so is desirable but not critical, and can be done later on.

Motivation

The version-string scheme introduced by JEP 223 was a significant improvement over that of the past. That scheme is not, however, well-suited to the future, in which we intend to ship new releases of the Java SE Platform and the JDK on a strict, six-month cadence.

The main difficulty with the JEP 223 scheme is that a release's version number encodes its significance and compatibility relative to its predecessors. In a time-based release model, however, these qualities are not known in advance. They are subject to change throughout a release's development cycle, until the final feature is integrated. A release's version number is therefore also not known in advance.

With JEP 223's semantics of version numbers, everyone who works on a release of the JDK, or builds or uses components on top of it, will have to speak initially of the release's ship date and then switch to speaking of the version number, once it is known. Developers who maintain libraries, frameworks, and tools will have to be prepared to change code that inspects version numbers late in each and every JDK release cycle. This is awkward and confusing for all involved.

The principal change proposed here is, therefore, to recast version numbers to encode not compatibility and significance but, rather, the passage of time, in terms of release cycles. This is a better fit for time-based release models since each release cycle, and thus each release's version number, is always known well in advance.

Description

Version numbers

A version number, $VNUM, is a non-empty sequence of elements separated by period characters (U+002E). An element is either zero, or an unsigned integer numeral without leading zeros. The final element of a version number must not be zero. When an element is incremented, all subsequent elements are removed. The format is:

[1-9][0-9]*((\.0)*\.[1-9][0-9]*)*

The sequence may be of arbitrary length but the first four elements are assigned specific meanings, as follows:

$FEATURE.$INTERIM.$UPDATE.$PATCH

The fifth and later elements of version numbers are reserved for use by downstream consumers of the JDK code base. The fifth element may be used to, e.g., identify implementor-specific patch releases.

A version number never has trailing zero elements. If an element and all those that follow it logically have the value zero then all of them are omitted.

The sequence of numerals in a version number is compared to another such sequence in numerical, pointwise fashion; e.g., 10.0.4 is less than 10.1.2. If one sequence is shorter than another then the missing elements of the shorter sequence are considered to be less than the corresponding elements of the longer sequence; e.g., 10.0.2 is less than 10.0.2.1.

Version numbers in the six-month release model

Under the six-month release model the elements of version numbers vary as follows:

We do expect most feature releases to contain at least one or two significant features, and for update releases never to include incompatible changes. In combination with the fact that $INTERIM is always zero, in practice this scheme will often define version numbers that are not much different from what the JEP 223 scheme would have defined.

Version strings

The overall format of version strings is the same as that defined in JEP 223. A version string is a version number, $VNUM, possibly followed by pre-release, build, and other optional information, one of:

$VNUM(-$PRE)?\+$BUILD(-$OPT)?
$VNUM-$PRE(-$OPT)?
$VNUM(+-$OPT)?

where $PRE is a pre-release identifier (e.g., ea), $BUILD is a build number, and $OPT is optional build information.

If a release is part of a series of releases for which an implementor offers long-term support then the value of $OPT should start with "LTS", e.g., 11.0.2+13-LTS. This will cause "LTS" to be displayed prominently in the output of java --version, etc., more on which below.

API

We revise the Runtime.Version API defined by JEP 223 as follows:

System properties

To the system properties mentioned in JEP 223 we add two new properties:

This new property makes it easy to figure out how old a release is, so that as a user you can understand how far behind you are. It also reflects the security level of the release: A given GA release contains the latest security fixes if its version date is no earlier than that of any other GA release.

This new property makes it possible for implementors to provide additional version information as may be necessary to align with related products. An implementor whose product line uses, e.g., date-based versions of the form $YEAR.$MONTH could set this property accordingly so that their JDK releases are clearly related to their other releases. (This property is named java.vendor.version rather than the more obvious java.implementor.version in order to be consistent with the existing system properties whose names include vendor.)

Launcher

The java launcher will display version strings and system properties as follows, for a hypothetical build 13 of JDK 10.0.1:

$ java --version
openjdk 10.0.1 2018-04-19
OpenJDK Runtime Environment (build 10.0.1+13)
OpenJDK 64-Bit Server VM (build 10.0.1+13, mixed mode)
$

Similarly, for a hypothetical build 42 of JDK 11, an LTS release:

$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment (build 11+42-LTS)
OpenJDK 64-Bit Server VM (build 11+42-LTS, mixed mode)
$

If an implementor assigns a vendor version string of, e.g., 18.9 to a JDK 11 LTS build then it would be displayed:

$ java --version
openjdk 11 2018-09-20 LTS
OpenJDK Runtime Environment 18.9 (build 11+42-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11+42-LTS, mixed mode)
$

In detail, the output of the java launcher's version-report options will be formatted as follows, where ${LTS} expands to "\u0020LTS" if the first three characters of $OPT are "LTS", and ${JVV} expands to "\u0020${java.vendor.version}" if that system property is defined:

$ java --version
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$ 

$ java --show-version < ... >
openjdk ${java.version} ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$ 

$ java --full-version
openjdk ${java.runtime.version}
$ 

$ java -version
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
$ 

$ java -showversion < ... >
openjdk version \"${java.version}\" ${java.version.date}${LTS}
${java.runtime.name}${JVV} (build ${java.runtime.version})
${java.vm.name}${JVV} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$ 

$ java -fullversion
openjdk full version \"${java.runtime.version}\"
$

@since JavaDoc tag

The value used with the @since JavaDoc tag continues to be aligned with the system property java.specification.version, hence APIs introduced in JDK 10 will be tagged @since 10.

Mercurial changeset tags

The general syntax for the Mercurial tags that identify promoted builds is unchanged: jdk\-$VNUM\+$BUILD.

Build configuration and output

Three existing version-related configuration options will be deprecated and hence ignored, and the related Make variables will no longer be defined:

--with-version-major          VERSION_MAJOR
--with-version-minor          VERSION_MINOR
--with-version-security       VERSION_SECURITY

Five new options, and corresponding variables, will be defined:

--with-version-feature        VERSION_FEATURE
--with-version-interim        VERSION_INTERIM
--with-version-update         VERSION_UPDATE
--with-version-date           VERSION_DATE
--with-vendor-version-string  VENDOR_VERSION_STRING

(There is no need to define --with-version-patch and VERSION_PATCH, since they already exist.)

The release file written into the root of a JDK image will, in addition to defining the existing JAVA_VERSION variable, also define JAVA_VERSION_DATE with the value of the java.version.date system property, and IMPLEMENTOR_VERSION with the value of the java.vendor.version system property, if defined.

Alternatives

The proposal for the six-month time-based release model suggested that the version strings of feature releases be of the form $YEAR.$MONTH. Thus next year's March release would be 18.3, the September release would be 18.9, and so on each year.

After reasonable objections were raised against this scheme we reviewed the various types of information encoded in version numbers and suggested some alternatives, then summarized and responded to the discussion that followed, and finally published a proposal that was well received and hence became the basis for this JEP.

Testing

This newer version-string scheme is largely compatible with that defined by JEP 223, so testing should be straightforward. The principal difference is the potential use of the fourth element for emergency patch releases, which may require some new unit-test cases. Changes to the relevant build-configuration options will require straightforward manual testing.

Risks and Assumptions

The changes described here introduce three minor incompatibilities: