Java 10 Time-Based Release Versioning and Runtime.Version
Introduction
Java 10 was the first release under Java's six-month release cadence, and with it Java adopted a new, time-based way of numbering its versions (JEP 322). This tutorial explains time-based release versioning in Java. We will first see why the release model changed and how long-term support (LTS) releases fit into it. We will then go through each part of a version number such as
From Java 10, a new feature release ships every six months, in March and September, with whatever features are ready by then. A feature which is not ready simply goes into a later release. Java 10 came out in March 2018, Java 11 in September 2018, and so on.
Each feature release gets updates only until the next one comes out. To give organisations a version they can stay on for years, some releases are designated long-term support (LTS) releases, which vendors keep updating for several years. Java 11 was the first LTS release under the new model, followed by Java 17, 21 and 25 - since Java 17, an LTS release comes every two years.
The version number format
Java versions now follow the format -
OUTPUT of the above code
Explanation of the code
Parsing and comparing versions
OUTPUT of the above code
Explanation of the code
11.0.21+9. Lastly, we will read and compare versions in code with the Runtime.Version API, which got new methods in Java 10.
From feature-driven to time-driven releases
Until Java 9, a major Java release shipped when its big features were ready. This made release dates unpredictable - Java 9, for example, was delayed several timesClick to read: delayed several times waiting for the module system, and came more than three years after Java 8. Finished smaller features had to wait for the big ones.From Java 10, a new feature release ships every six months, in March and September, with whatever features are ready by then. A feature which is not ready simply goes into a later release. Java 10 came out in March 2018, Java 11 in September 2018, and so on.
Each feature release gets updates only until the next one comes out. To give organisations a version they can stay on for years, some releases are designated long-term support (LTS) releases, which vendors keep updating for several years. Java 11 was the first LTS release under the new model, followed by Java 17, 21 and 25 - since Java 17, an LTS release comes every two years.
$FEATURE.$INTERIM.$UPDATE.$PATCH- $FEATURE - the feature release, incremented every six months: 10, 11, 12 and so on. It is the number people mean when they say "Java 11".
- $INTERIM - for a release between feature releases with compatible fixes. The six-month model has no need for such releases, so it is always
0. - $UPDATE - incremented for each update release with security and bug fixes, released every quarter in January, April, July and October. For example,
11.0.21is the 21st update of Java 11. - $PATCH - for an emergency patch release outside the quarterly schedule. It is rarely used.
11, not 11.0.0.0. A full version string can also have a build number after a +, and optional information after a -, as in 21.0.5+11-LTS. This replaced the older scheme, in which Java 8 updates were numbered like 1.8.0_202, and Java 9 used $MAJOR.$MINOR.$SECURITY, as in 9.0.4.
Reading the version with Runtime.Version
Java 9 added the Runtime.Version class, which represents a version string and can be parsed and compared. Java 10 added the methods feature(), interim(), update() and patch(), matching the new format, and deprecated Java 9's major(), minor() and security(). Runtime.version() returns the version of the running JVM -
Reading the running Java version
//VersionDemo.java
public class VersionDemo {
public static void main(String[] args) {
Runtime.Version version = Runtime.version();
System.out.println("Version : " + version);
System.out.println("feature : " + version.feature());
System.out.println("interim : " + version.interim());
System.out.println("update : " + version.update());
System.out.println("patch : " + version.patch());
System.out.println("build : " + version.build().orElse(-1));
System.out.println("java.version property: " + System.getProperty("java.version"));
if (version.feature() >= 11) {
System.out.println("Running on Java 11 or later - the HTTP Client is available");
}
}
}
Version : 24.0.1+9-30 feature : 24 interim : 0 update : 1 patch : 0 build : 9 java.version property: 24.0.1 Running on Java 11 or later - the HTTP Client is available
- This output is from JDK 24.0.1, build 9. Run the program on your own JDK and the numbers will match your version.
version.feature()is the simplest way to check for a minimum Java version. Before Java 9, code had to parse thejava.versionsystem property, which was error-prone because of the1.8.0_202style format.build()returns anOptional<Integer>, because a version string does not always have a build number.
Runtime.Version.parse() parses any version string, and versions can be compared with compareTo(), which compares them number by number rather than as text -
Parsing and comparing version strings
//VersionCompareDemo.java
import java.util.List;
import java.util.stream.Collectors;
public class VersionCompareDemo {
public static void main(String[] args) {
List<String> strings = List.of("11.0.21+9", "10", "17.0.2", "9.0.4", "11.0.3", "21.0.5+11-LTS");
for (String s : strings) {
Runtime.Version v = Runtime.Version.parse(s);
System.out.printf("%-14s feature=%-3d update=%-3d build=%s%n",
s, v.feature(), v.update(), v.build().map(String::valueOf).orElse("-"));
}
List<String> sorted = strings.stream()
.map(Runtime.Version::parse)
.sorted()
.map(Runtime.Version::toString)
.collect(Collectors.toList());
System.out.println("Sorted: " + sorted);
// 11.0.21 is newer than 11.0.3, although "11.0.21" < "11.0.3" as text
System.out.println("Text comparison says 11.0.21 is newer: " + ("11.0.21".compareTo("11.0.3") > 0));
System.out.println("Version comparison says 11.0.21 is newer: "
+ (Runtime.Version.parse("11.0.21").compareTo(Runtime.Version.parse("11.0.3")) > 0));
}
}
11.0.21+9 feature=11 update=21 build=9 10 feature=10 update=0 build=- 17.0.2 feature=17 update=2 build=- 9.0.4 feature=9 update=4 build=- 11.0.3 feature=11 update=3 build=- 21.0.5+11-LTS feature=21 update=5 build=11 Sorted: [9.0.4, 10, 11.0.3, 11.0.21+9, 17.0.2, 21.0.5+11-LTS] Text comparison says 11.0.21 is newer: false Version comparison says 11.0.21 is newer: true
- The old Java 9 version
9.0.4is parsed with the same rules, so its third number appears as the update number. Runtime.VersionimplementsComparable, so a list of versions sorts in the correct order. Comparing the strings as text would put11.0.21before11.0.3, because the character'2'comes before'3'.compareTo()also takes the build number and optional information into account.compareToIgnoreOptional()ignores the optional part after the-.
$FEATURE.$INTERIM.$UPDATE.$PATCH version format. We then read the running Java version with Runtime.version() and the feature(), interim(), update() and patch() methods added in Java 10, and parsed and compared version strings. In the next tutorial, we will see how to generate JNI headers with javac -hClick to read tutorial: Java 10 Removed javah: Generate JNI Headers with javac -h, now that Java 10 has removed the javah tool.Continue Reading Java 9 & Java 10 Tutorials
Java 10 Removed javah: Generate JNI Headers with javac -hClick to read tutorial: Java 10 Removed javah: Generate JNI Headers with javac -h Java 10 Application Class-Data Sharing (AppCDS) TutorialClick to read tutorial: Java 10 Application Class-Data Sharing (AppCDS) Tutorial Overview of New Features in Java 10Click to read tutorial: Overview of New Features in Java 10 Java var Keyword: Local Variable Type InferenceClick to read tutorial: Java var Keyword: Local Variable Type Inference Java 10 API Additions: copyOf, toUnmodifiableList & MoreClick to read tutorial: Java 10 API Additions: copyOf, toUnmodifiableList & More Java 10 Unicode Locale Extensions: Currency, Week, RegionClick to read tutorial: Java 10 Unicode Locale Extensions: Currency, Week, Region Java 9 Modules Tutorial | Java Platform Module System (JPMS)Click to read tutorial: Java 9 Modules Tutorial | Java Platform Module System (JPMS)
Java 10 Removed javah: Generate JNI Headers with javac -hClick to read tutorial: Java 10 Removed javah: Generate JNI Headers with javac -h Java 10 Application Class-Data Sharing (AppCDS) TutorialClick to read tutorial: Java 10 Application Class-Data Sharing (AppCDS) Tutorial Overview of New Features in Java 10Click to read tutorial: Overview of New Features in Java 10 Java var Keyword: Local Variable Type InferenceClick to read tutorial: Java var Keyword: Local Variable Type Inference Java 10 API Additions: copyOf, toUnmodifiableList & MoreClick to read tutorial: Java 10 API Additions: copyOf, toUnmodifiableList & More Java 10 Unicode Locale Extensions: Currency, Week, RegionClick to read tutorial: Java 10 Unicode Locale Extensions: Currency, Week, Region Java 9 Modules Tutorial | Java Platform Module System (JPMS)Click to read tutorial: Java 9 Modules Tutorial | Java Platform Module System (JPMS)