JEP 223: New Version-String SchemeJEP 223: New Version-String SchemeAuthorsIris Clark, Mark ReinholdOwnerIris ClarkTypeFeatureScopeSEStatusClosed / DeliveredRelease9Discussionverona dash dev at openjdk dot java dot netEffortMDurationMRelates to8085822: JEP 223: New Version-String Scheme (initial integration)Reviewed byBrian Goetz, Roger RiggsEndorsed byBrian GoetzCreated2014/10/20 18:27Updated2021/10/03 12:50Issue8061493Summary
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.


Be adoptable by existing packaging systems and platform-deployment
mechanisms including RPM, dpkg, IPS, and the
Java Network Launching Protocol (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.


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 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.
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


$MAJOR --- 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 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.


$MINOR --- 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 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.


$SECURITY --- 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.
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:


$PRE, matching ([a-zA-Z0-9]+) --- A
pre-release identifier. 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.


$BUILD, matching (0|[1-9][0-9]*) --- The
build number, incremented for each promoted build. $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.


$OPT, matching ([-a-zA-Z0-9\.]+) --- Additional
build information, if desired. 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 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, 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.
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.
System properties
The values returned by the following system properties 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.
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.
@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 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.
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.
InstallingContributingSponsoringDevelopers' GuideVulnerabilitiesJDK GA/EA BuildsMailing listsWiki
                      · IRCBylaws · CensusLegalWorkshopJEP ProcessSource codeMercurialGitHubToolsGitjtreg harnessGroups(overview)AdoptionBuildClient LibrariesCompatibility & Specification ReviewCompilerConformanceCore LibrariesGoverning BoardHotSpotIDE Tooling & SupportInternationalizationJMXMembersNetworkingPortersQualitySecurityServiceabilityVulnerabilityWebProjects(overview,
      archive)AmberBabylonCRaCCaciocavalloClosuresCode ToolsCoinCommon VM InterfaceCompiler GrammarDetroitDevelopers' GuideDevice I/ODukeGalahadGraalIcedTeaJDK 7JDK 8JDK 8 UpdatesJDK 9JDK
      (…,
       21,
       22,
       23)JDK UpdatesJavaDoc.NextJigsawKonaKullaLambdaLanaiLeydenLilliputLocale EnhancementLoomMemory Model UpdateMetropolisMission ControlMulti-Language VMNashornNew I/OOpenJFXPanamaPenrosePort: AArch32Port: AArch64Port: BSDPort: HaikuPort: Mac OS XPort: MIPSPort: MobilePort: PowerPC/AIXPort: RISC-VPort: s390xPortolaSCTPShenandoahSkaraSumatraTiered AttributionTsanType AnnotationsValhallaVeronaVisualVMWakefieldZeroZGC

        © 2024 Oracle Corporation and/or its affiliates
        Terms of Use
        ·
        
            License: GPLv2
        · Privacy
        · Trademarks
