But you can confuse them…

I don’t envy Mark Reinhold’s job. As Chief Architect of the Java Platform Group at Oracle, he has literally millions of Java developers to keep happy. That’s no simple task.

Just before JavaOne, there were a number of announcements made about the Java platform including a move to a strict six-month release cadence as well as a proposal for a new JDK version-string scheme.

It’s fair to say that the Java community responded very favourably to the idea that there would be a new feature release of Java twice a year. One complaint about Java in the past has been the rate at which new features have been made available. In theory, the release cadence since Oracle acquired Sun Microsystems has been two years. In practice that hasn’t been the case. JDK 7 was released in July 2011, which was over four and a half years from JDK 6. (To be fair, there were more than just technical reasons for the length of time between those two releases). JDK 8 emerged into the light of day just under three years later and, with the launch of JDK 9, this September, it was three and a half years between releases.

With a strict release schedule, release contents will be driven by what is ready to ship not what is targeted for a specific release. Fewer changes in each release but the opportunity to get changes more quickly.

So far, so good.

However, the proposal for the new version-numbering scheme was less well received.

It might seem that version numbering should be relatively straightforward, but that is not the case in reality. Historically, Java has had what could best be described as a somewhat schizophrenic version numbering scheme.

For fun, let’s look back at the history of Java versions.

In the beginning, we had JDK 1.0. OK, that makes sense, the very first official (non-beta) version with the possibility (signified by the .0 extension) of further updates. The problem immediately becomes, what qualifies as an update? The next version, JDK 1.1, included reasonably significant new features like inner classes and reflection. With hindsight, this would have been better termed JDK 2.0.

Things all went a bit weird when the next version was released. The way I describe this is a situation where marketing clashed with engineering, and neither would concede defeat. At this point, Java was sort of rebranded (input from marketing) to Java 2. It was also divided into three distinct technological groupings. Thus we had Java 2 Micro Edition (ME) for phones and embedded applications, Java 2 Standard Edition (SE), for the core platform and Java 2 Enterprise Edition (EE) for app server container-based applications. This should have been fine; except engineering somehow didn’t buy into this (at least not for Java SE) and so we ended up with Java 2 SE version 1.2. This, to me, was a big mistake, why keep the 1. prefix and not change it to 2.0?

To make things even more confusing, the next version was Java 2 SE version 1.3 shortly followed by an update with smaller changes, Java 2 SE version 1.3.1. The addition of a further subdivision seems somewhat arbitrary, given the previous release numbering. At this point marketing decided that Java 3 wasn’t going to happen (more likely, whoever was in charge of marketing at Sun when the Java 2 decision was made had moved on to pastures new) and we got a distinction between the Java brand (Java 2 SE) and the JDK, so JDK 1.4, JDK 1.4.1 and JDK 1.4.2.

The next version of Java included the most significant set of changes to the language since it was launched (enumerations, generic types, etc.) as well as substantial new libraries (e.g., the concurrency utilities). A decision was made that this should be reflected in the version number. Thus we had Java 2 SE version 5.0. Unfortunately, engineering, presumably mindful of the issues of compatibility, stuck with the existing numbering scheme internally so java –version initially returned 1.5.0. However, periodic updates including bug and security fixes were required, so an official update scheme was introduced. This gave us Java 2 SE 5.0 update 1 and jdk1.5.0.1 from java –version. (I’ve not been able to test this, but I seem to remember that it was in this form).

With new blood in Sun marketing, the decision was made to simplify things (well, they couldn’t really be made more complicated) so the next release was the cleaned up, stripped down, Java SE 6. No more 2 (there would never be a 3, so it was kind of redundant) and the .0 was officially dropped. java –version still returned jdk1.6.0.1, however. (Again, this is from my memory, not confirmed)

The next ten years were a period of relative version numbering stability giving us Java SE 7 (JDK 1.7.0) and Java SE 8 (JDK 1.8.0). The only thing of note that changed was the numbering for updates. This switched to an increment of five for each limited update release or critical patch update (CPU), which is Oracle terminology. The reason for this was these releases were scheduled for each quarter and in the event of an emergency patch before the planned release date there needed to be numbers available. Also, at some point (that I’m unable to determine) the value returned by java –version started to use an underscore rather than a period for the update, so it became jdk1.8.0_131, for example.

With JDK 9 having a number of incompatible changes, the decision was made to clean up the version numbering properly once and for all. This was described in JEP 223, and we now have a more semantic version numbering scheme. The specification for the core platform is Java SE 9 (defined through JSR 379), and the JDK version is now $MAJOR.$MINOR.$PATCH (e.g. 9.0.5).

At this point, it would seem that everything is good.

Unfortunately not. As I mentioned at the start of this blog, the new, six-month, release cadence for the JDK also prompted a proposal for a new version-string format. This would be based on the date of the release since this would be fixed. Thus, the next release of Java would be Java SE 18.3 (18 for the year, 2018 and 3 for the month, March). Others have used this in the past, most obviously Ubuntu.

Unfortunately, this was not met with the same universal acceptance that the idea of a six-month release cadence was. Personally, I didn’t see any problems with this, but some in the community did raise significant objections.

Based on this feedback, Mark has revised the proposed numbering scheme. We now have a defined four digit scheme: $FEATURE.$INTERIM.$UPDATE.$EMERG. Full details of this can be found in Mark’s post on the jdk-dev mailing list.

This seems more popular than the YEAR.MONTH scheme but Stephen Colebourne in particular still doesn’t like this. I spoke to Mark about this at JavaOne, and he made a good point, which I think Stephen is overlooking. If you ignore the changes to the numbering scheme and think of this in terms of what we’ve had before the only difference is that update releases of the JDK can now contain feature changes, either addition (or removal) of features.

The biggest problem faced by Java is how to appeal to two distinctly different audiences of developers. On the one hand, you have big commercial users who want stability with long-term publicly available security and bug fixes. On the other, you have cutting-edge developers who want access to the latest features as quickly as possible. The third change that was announced at the same time as the new release cadence and version-string scheme solves this dilemma.

Java releases will be divided into two groups:

Feature releases. These will have public updates only until the next feature release, i.e., for six months. These are, in effect, the same as the update releases we’ve been used to with the exception that they can contain new features or remove previously deprecated ones. Long-term support (LTS) releases. These are the same as a feature release, except that they will have publicly available updates for three years. Bug and security fixes from future feature releases will be back-ported to these releases. JDK 8 is an LTS release, and the next one will be in September next year so JDK 11. Just to be clear on this, JDK 9 is a Feature release, not an LTS one.

Commercial users looking for stability only really have the option of using the LTS releases, upgrading every three years. For leading-edge developers, they can take whichever release they want for the new features and move in a more agile way but accepting that they will need to upgrade every six months.

I will point out that Azul, as a provider of extremely reasonably priced OpenJDK Java support, is actively looking at how we can offer extended support for Feature releases. Watch this space for further details on this.

Hopefully, the new numbering scheme will be approved, and Java 10 will be the next release.

Or should we call it Java X?