|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
JDK-8072375 :
|
|
|
JDK-8072376 :
|
|
|
JDK-8072378 :
|
|
|
JDK-8072379 :
|
|
|
JDK-8072633 :
|
|
|
JDK-8072806 :
|
|
|
JDK-8087202 :
|
|
|
JDK-8087203 :
|
|
|
JDK-8098588 :
|
Summary
-------
Define a version-string scheme that easily distinguishes major, minor, and security-update releases, and apply it to the JDK.
Goals
-----
- Be easily understandable by humans, and easily parsable by programs.
- Align with current industry practices, in particular
[Semantic Versioning][semver].
- Be adoptable by existing packaging systems and platform-deployment
mechanisms including [RPM][rpm], [dpkg][dpkg], [IPS][ips], and the
[Java Network Launching Protocol (JNLP)][jnlp].
- Eliminate the current practice of encoding two types of information
in one element of the version string, _i.e._, the minor release
number and the security level, which is difficult to decipher and
results in skipping many version numbers.
- Provide a simple API for version-string parsing, validation, and
comparison.
[semver]: http://semver.org/
[dpkg]: https://en.wikipedia.org/wiki/Dpkg
[rpm]: https://en.wikipedia.org/wiki/RPM_Package_Manager
[ips]: https://en.wikipedia.org/wiki/Image_Packaging_System
[jnlp]: https://en.wikipedia.org/wiki/JNLP
Non-Goals
---------
- Change the version-string format used by any release prior to this
JEP's targeted release.
Motivation
----------
Which release contains all of the most recent security fixes: JDK 7
Update 55, or JDK 7 Update 60?
It looks like JDK 7 Update 60 is five releases later than Update 55, so
therefore it must include more security fixes, right?
That conclusion is, sadly, incorrect: These two releases both contain
exactly the same security fixes. To understand this answer, you first
need to understand the [current numbering scheme][ns] for JDK Update
releases. Minor releases containing changes beyond security fixes are
multiples of 20. Security releases based on the previous minor
release are odd numbers incremented by five, or by six if necessary in
order to keep the update number odd. To understand whether a minor
release is actually more secure than an earlier release ultimately
requires looking at the release notes or the source code.
What's the difference between releases named "JDK 7 Update 60",
"1.7.0_60", and "JDK 7u60"?
These are just different names for the same release. These differences
make it difficult to identify and verify equivalent releases. A simple
pointwise comparison of sequences of parsed tokens does not suffice;
instead, a fairly sophisticated algorithm is needed. The use of the
lower-case 'u' is not an industry standard and is not language-neutral.
It's long past time for a simpler, more intuitive versioning scheme.
[ns]: http://www.oracle.com/technetwork/java/java-update-release-numbers-change-1836624.html
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 in a version
number must not be zero. The format is:
[1-9][0-9]*((\.0)*\.[1-9][0-9]*)*
The sequence may be of arbitrary length but the first three elements are
assigned specific meanings, as follows:
$MAJOR.$MINOR.$SECURITY
- <a id="descMAJOR">`$MAJOR`</a> --- The major version number,
incremented for a major release that contains significant new
features as specified in a new edition of the Java SE Platform
Specification, _e.g._, [JSR 337][se8] for Java SE 8.
Features may be removed in a major release, given advance notice at
least one major release ahead of time, and incompatible changes may
be made when justified. The `$MAJOR` version number of JDK 8
is `8`; the `$MAJOR` version number of JDK 9 is `9`. When
`$MAJOR` is incremented, all subsequent elements are removed.
- <a id="descMINOR">`$MINOR`</a> --- The minor version number,
incremented for a minor update release that may contain compatible
bug fixes, revisions to standard APIs mandated by a
[Maintenance Release][mr] of the relevant Platform Specification, and
implementation features outside the scope of that Specification such
as new JDK-specific APIs, additional service providers, new garbage
collectors, and ports to new hardware architectures.
- <a name="descSEC">`$SECURITY`</a> --- The security level, incremented
for a security-update release that contains critical fixes including
those necessary to improve security. `$SECURITY` is **not** reset to
zero when `$MINOR` is incremented. A higher value of `$SECURITY`
for a given `$MAJOR` value, therefore, always indicates a more secure
release, regardless of the value of `$MINOR`.
The fourth and later elements of a version number are free for use by
downstream consumers of the JDK code base. Such a consumer may, _e.g._,
use the fourth element to identify patch releases which contain a small
number of critical non-security fixes in addition to the security fixes
in the corresponding security release.
The version number does not include trailing zero elements; _i.e._,
`$SECURITY` is omitted if it has the value zero, and `$MINOR` is omitted
if both `$MINOR` and `$SECURITY` have the value zero.
The sequence of numerals in a version number is compared to another such
sequence in numerical, pointwise fashion; _e.g._, `9.9.1` is less than
`9.10.3`. 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._, `9.1.2` is less than
`9.1.2.1`.
[se8]: https://jcp.org/en/jsr/detail?id=337
[mr]: https://jcp.org/en/procedures/jcp2#5.2
### Version strings
A _version string_, `$VSTR`, consists of a version number `$VNUM`, as
described above, optionally followed by pre-release and build information,
in one of the following formats:
$VNUM(-$PRE)?\+$BUILD(-$OPT)?
$VNUM-$PRE(-$OPT)?
$VNUM(+-$OPT)?
where:
- <a name="descPRE"/>`$PRE`, matching `([a-zA-Z0-9]+)` --- A
pre-release identifier.</a> Typically `ea`, for an early-access
release that's under active development and potentially unstable, or
`internal`, for an internal developer build.
When comparing two version strings, a string with a pre-release
identifier is always less than one with an equal `$VNUM` but no such
identifier. Pre-release identifiers are compared numerically when
they consist only of digits, and lexicographically otherwise.
Numeric identifiers are considered to be less than non-numeric
identifiers.
- <a name="descBUILD"/>`$BUILD`, matching `(0|[1-9][0-9]*)` --- The
build number, incremented for each promoted build.</a> `$BUILD` is
reset to one when any portion of `$VNUM` is incremented.
When comparing two version strings with equal `$VNUM` and `$PRE`
components, a string without a `$BUILD` component is always less than
one with a `$BUILD` component; otherwise, `$BUILD` numbers are
compared numerically.
- <a name="descSTR"/>$OPT, matching `([-a-zA-Z0-9\.]+)` --- Additional
build information, if desired.</a> In the case of an `internal` build
this will often contain the date and time of the build.
When comparing two version strings the value of `$OPT`, if present, may
or may not be significant depending on the chosen comparison method.
A version number `10-ea` matches `$VNUM = "10"` and `$PRE = "ea"`. The
version number `10+-ea` matches `$VNUM = "10"` and `$OPT = "ea"`.
The following table compares potential version strings for JDK 9,
using the existing and proposed formats:
Existing Proposed
Release Type long short long short
------------ -------------------- --------------------
Early Access 1.9.0-ea-b19 9-ea 9-ea+19 9-ea
Major 1.9.0-b100 9 9+100 9
Security #1 1.9.0_5-b20 9u5 9.0.1+20 9.0.1
Security #2 1.9.0_11-b12 9u11 9.0.2+12 9.0.2
Minor #1 1.9.0_20-b62 9u20 9.1.2+62 9.1.2
Security #3 1.9.0_25-b15 9u25 9.1.3+15 9.1.3
Security #4 1.9.0_31-b08 9u31 9.1.4+8 9.1.4
Minor #2 1.9.0_40-b45 9u40 9.2.4+45 9.2.4
For reference, this table shows version strings in the new format as they
would have been used, hypothetically, for some JDK 7 update and
security releases:
Actual Hypothetical
Release Type long short long short
------------ -------------------- -------------------
Security 2013/04 1.7.0_21-b11 7u21 7.4.10+11 7.4.10
Security 2013/06 1.7.0_25-b15 7u25 7.4.11+15 7.4.11
Minor 2013/09 1.7.0_40-b43 7u40 7.5.11+43 7.5.11
Security 2013/10 1.7.0_45-b18 7u45 7.5.12+18 7.5.12
Security 2014/01 1.7.0_51-b13 7u51 7.5.13+13 7.5.13
Security 2014/04 1.7.0_55-b13 7u55 7.5.14+13 7.5.14
Minor 2014/05 1.7.0_60-b19 7u60 7.6.14+19 7.6.14
Security 2014/07 1.7.0_65-b20 7u65 7.6.15+20 7.6.15
### Dropping the initial `1` element from version numbers
This proposal drops the initial `1` element from JDK version numbers.
That is, it suggests that the first release of JDK 9 will have the
version number `9.0.0` rather than `1.9.0.0`.
After nearly twenty years it's clear that the second element of the
current version-number scheme is the JDK's _de facto_ `$MAJOR` version
number. We increment that element when we add significant new features,
and also when we make incompatible changes.
We could start treating the initial element of the current scheme as the
`$MAJOR` version number, but then JDK 9 would have the version number
`2.0.0` even though everyone already refers to it as "JDK 9". This would
help no one.
If we retain the initial `1` then JDK version numbers will continue to
violate the principles of [Semantic Versioning][semver] and developers
new to Java will continue to be confused about the difference between,
_e.g._, `1.9` and `9`.
There is some risk in dropping the initial `1`. There are many ways to
compare version numbers; some will work correctly, while some will not.
- Existing code that compares version numbers by parsing their elements
and comparing them numerically will continue to work, since nine is
greater than one; _i.e._, `9.0.0` will be considered to be later than
`1.8.0`.
- Existing code that skips the initial element when it has the value
`1` will also continue to work, since in the new scheme the initial
element will never have that value.
- Existing code that assumes the initial element to have the value `1`,
however, and therefore always skips to the second element when
comparing version numbers, will not work correctly; _e.g._, such code
will consider `9.0.1` to precede `1.8.0`.
Anecdotal evidence suggests that existing code in the third category is
not very common, but we would welcome data to the contrary.
### API
A simple Java API to parse, validate, and compare version strings will
be defined ([8072379][8072379], [8144062][8144062]):
[8072379]: https://bugs.openjdk.java.net/browse/JDK-8072379
[8144062]: https://bugs.openjdk.java.net/browse/JDK-8144062
package java.lang;
import java.util.Optional;
public class Runtime {
public static Version version();
public static class Version
implements Comparable<Version>
{
public static Version parse(String);
public int major();
public int minor();
public int security();
public List<Integer> version();
public Optional<String> pre();
public Optional<Integer> build();
public Optional<String> optional();
public int compareTo(Version o);
public int compareToIgnoreOpt(Version o);
public boolean equals(Object o);
public boolean equalsIgnoreOpt(Object o);
public String toString();
public int hashCode();
}
}
An equivalent C API will be defined, most likely in terms of a revised
[jvm_version_info struct][jvmh].
All code in the JDK that inspects and compares JDK version strings will
be updated to use these APIs. Developers whose libraries or applications
inspect and compare JDK version strings will be encouraged to use these
APIs.
[jvmh]: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/native/include/jvm.h
### System properties
The values returned by the following [system properties][props] are modified
by this JEP. The general syntax is as follows:
Name Syntax
------------------------------ --------------
java.version $VNUM(\-$PRE)?
java.runtime.version $VSTR
java.vm.version $VSTR
java.specification.version $VNUM
java.vm.specification.version $VNUM
The system property `java.class.version` is not affected.
The following table shows the existing and proposed values for different
release types:
System Property Existing Proposed
------------------------------- ------------ --------
Early Access
java.version 1.9.0-ea 9-ea
java.runtime.version 1.9.0-ea-b73 9-ea+73
java.vm.version 1.9.0-ea-b73 9-ea+73
java.specification.version 1.9 9
java.vm.specification.version 1.9 9
Major (GA)
java.version 1.9.0 9
java.runtime.version 1.9.0-b100 9+100
java.vm.version 1.9.0-b100 9+100
java.specification.version 1.9 9
java.vm.specification.version 1.9 9
Minor #1 (GA)
java.version 1.9.0_20 9.1.2
java.runtime.version 1.9.0_20-b62 9.1.2+62
java.vm.version 1.9.0_20-b62 9.1.2+62
java.specification.version 1.9 9
java.vm.specification.version 1.9 9
Security #1 (GA)
java.version 1.9.0_5 9.0.1
java.runtime.version 1.9.0_5-b20 9.0.1+20
java.vm.version 1.9.0_5-b20 9.0.1+20
java.specification.version 1.9 9
java.vm.specification.version 1.9 9
Note that all code which has historically detected `.` in any of these system
properties as part of version identification will need to be examined and
potentially modified. For example,
`System.getProperty("java.version").indexof('.')` will return `-1` for major
releases.
[props]: http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getProperties--
### Launcher ###
In the OpenJDK `java` launcher implementation, system properties are used when
reporting version information, e.g. `java -version`, `java -fullversion`, and
`java -showversion`.
The launcher output continues to depend on the system properties as follows:
$ java -version
openjdk version \"${java.version}\"
${java.runtime.name} (build ${java.runtime.version})
${java.vm.name} (build ${java.vm.version}, ${java.vm.info})
$ java -showversion < ... >
openjdk version \"${java.version}\"
${java.runtime.name} (build ${java.runtime.version})
${java.vm.name} (build ${java.vm.version}, ${java.vm.info})
[ ... ]
$ java -fullversion
openjdk full version \"${java.runtime.version}\"
Implementation details may be found in the [source][VerTemp].
[VerTemp]: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/sun/misc/Version.java.template
### `@since` JavaDoc tag
The value for the `@since` JavaDoc tag will continue to be aligned
with the system property `java.specification.version`; hence, new
JDK 9 APIs will be indicated by `@since 9`.
### Mercurial changeset tags
Mercurial tags are used to identify a promotion's changesets. Tools such
as [Code Tool's][codetools] [jcheck][jcheck], which is used to validate
all changesets pushed to JDK release forests, will be enhanced to support
tags using the new version scheme.
The general syntax for Mercurial tags is `jdk\-$VNUM\+$BUILD`. The following
table shows the proposed values for different release types:
Release Type Proposed
---------------- -----------
Major (GA) jdk-9+100
Minor #1 (GA) jdk-9.1.2+27
Security #1 (GA) jdk-9.0.1+3
Some tools may need to support both existing and proposed tag formats.
[codetools]: http://openjdk.java.net/code-tools
[jcheck]: http://hg.openjdk.java.net/code-tools/jcheck/file/tip/jcheck.py
Testing
-------
Changing the syntax and semantics of version strings will require
extensive testing of all component areas. Existing tests that are
independent of the JDK version string should continue to pass.
|