Close

Understanding Time-Based Release Versioning

[Last Updated: Apr 12, 2018]

Feature Release

Starting Java 10, a new strict, time-based release model has been adopted. In this new model, major releases (now called feature releases) of the Java platform will occur every 6 months (March and Sept).

Feature releases will contain language features, JVM features and new improved APIs. The feature release can also remove unwanted/deprecated old features.

The new time-based model has replaced the feature-based, multi-year release model of the past. Unlike the old releases, the new time-based releases will not be delayed and will be released every six months, with no constraints on what features can go out in the releases.

Update Release

The updates releases will occur every quarter (Jan, April, July, Oct).

Update releases will be strictly limited to fixes of security issues, regressions, and bugs in newer features.

Each feature release will receive two updates before the next feature release.

Long Term Release (LTS)

Every three years, starting in September of 2018, the feature release will be a long-term support release. Updates for these releases will be available for at least three years


Version Format

$FEATURE.$INTERIM.$UPDATE.$PATCH
  • $FEATURE: This counter will be incremented at every feature release regardless of release content. The feature counter for the current release is 10.

  • $INTERIM: This counter will be incremented for non-feature releases that contain compatible bug fixes and enhancements but no incompatible changes, no feature removals, and no changes to standard APIs.
    Since the six-month model does not include interim releases, this will always be zero. It is reserved for flexibility, so that a future revision may include something like JDK $N.1 and JDK $N.2 etc. For example, JDK 1.4.1 and 1.4.2 releases were interim releases, and according to the new versioning system, they would have been numbered 4.1 and 4.2.

  • $UPDATE: The update-release counter, incremented for compatible update releases.
    The April 2018 release will be JDK 10.0.1 with the update counter 1, the July release will be JDK 10.0.2 with the update counter 2, and so forth.

  • $PATCH: The emergency patch-release counter, incremented only when it's necessary to produce an emergency release to fix a critical issue.

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

Using Runtime.Version

java.lang.RuntimeVersion can be used to get version information.

public class VersionTest {
  public static void main(String[] args) {
      Runtime.Version version = Runtime.version();
      printVersionInfo(version);
  }

  private static void printVersionInfo(Runtime.Version version) {
      int feature = version.feature();
      int interim = version.interim();
      int update = version.update();
      int patch = version.patch();
      System.out.printf(" feature: %s%n interim: %s%n update: %s%n patch: %s%n",
              feature, interim, update, patch);
  }
}
 feature: 10
interim: 0
update: 0
patch: 0

We can also use Version#parse() method to test version strings. For example Java 10 next update (in April 2018) will have version string 10.0.1. Let's try that:

public class VersionParseTest {
  public static void main(String[] args) {
      Runtime.Version version = Runtime.Version.parse("10.0.1");
      printVersionInfo(version);
  }

  private static void printVersionInfo(Runtime.Version version) {
      int feature = version.feature();
      int interim = version.interim();
      int update = version.update();
      int patch = version.patch();
      System.out.printf(" feature: %s%n interim: %s%n update: %s%n patch: %s%n",
              feature, interim, update, patch);
  }
}
 feature: 10
interim: 0
update: 1
patch: 0

The old methods major() and minor() have been deprecated. They forward calls to feature() and interim() respectively:

public class VersionMajorMinor {
  public static void main(String[] args) {
      Runtime.Version version = Runtime.version();
      System.out.println(version.major());
      System.out.println(version.minor());
  }
}
10
0

Using SourceVersion

package com.logicbig.example;

import javax.lang.model.SourceVersion;

public class SourceVersionTest {
  public static void main(String[] args) {
      SourceVersion latest = SourceVersion.latest();
      System.out.println(latest);
  }
}
RELEASE_10

Version related new System properties

java.version.date: The general-availability (GA) date of this release.

java.vendor.version: An implementor-specific product version string.

public class VersionSystemProperties {
  public static void main(String[] args) {
      String versionDate = System.getProperty("java.version.date");
      System.out.println("java.version.date: " + versionDate);

      String vendorVersion = System.getProperty("java.vendor.version");
      System.out.println("java.vendor.version: " + vendorVersion);
  }
}
java.version.date: 2018-03-20
java.vendor.version: 18.3

Other than above new properties, followings are other version related properties:

public class VersionSystemProperties2 {
  public static void main(String[] args) {
      System.out.println("java.version: " +
              System.getProperty("java.version"));
      System.out.println("java.runtime.version: " +
              System.getProperty("java.runtime.version"));
      System.out.println("java.vm.version: " +
              System.getProperty("java.vm.version"));
      System.out.println("java.specification.version: " +
              System.getProperty("java.specification.version"));
      System.out.println("java.vm.specification.version: " +
              System.getProperty("java.vm.specification.version"));
  }
}
java.version: 10
java.runtime.version: 10+46
java.vm.version: 10+46
java.specification.version: 10
java.vm.specification.version: 10

Java Launcher version string

$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

The output of the java launcher is formatted as follows:

$ java --version
java 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})

The build number can also be found via Runtime.Version.build().

Class File Version Number

The class file version has been changed from 53 to 54 (JDK-8191510), even though JDK 10 did not introduce the changes to the class file format.

The class file version number can be seen via javap command:

$ javap -verbose output/com.logicbig.example.SourceVersionTest
Last modified Apr 2, 2018; size 723 bytes
MD5 checksum 7db715f4329811ca26194813f4f3e08b
Compiled from "SourceVersionTest.java"
public class com.logicbig.example.SourceVersionTest
minor version: 0
major version: 54
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #5 // com/logicbig/example/SourceVersionTest
super_class: #6 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
.......

Example Project

Dependencies and Technologies Used:

  • JDK 9.0.1
Time Based Release Versioning Select All Download
  • time-based-release-versioning
    • src
      • com
        • logicbig
          • example
            • VersionTest.java

    See Also