Radical new plans for Java

CodeFX Weekly #34 — 9th of September 2017

Hi everyone,

this week the JDK team proposed radical new plans for Java and for once an Oracle announcement was met with near universal praise from the community (that I live to see the day…). Java’s Guardians are planning radical changes in Java’s release cadence, licensing, commercial feature set, and universal presence on all machines. And it’s awesome! Mostly.

I send this newsletter out every Friday. Yes, as an actual email. Subscribe!


Six-monthly #Javatrain

As Mark Reinhold explains in his blog, for Java 8 and 9 the JDK team aimed for a fixed two-year release cycle — the features that are not ready in time will simply have to wait for the next release. While that sounded good in theory, it did not work as expected and both Java 8 and 9 were considerably delayed.

The problem was that pushing a headline feature like lambdas or the module system from one release to the next is a hard sell. Imagine having to wait for a feature you’re really looking forward to for another two years just because it overshot its deadline by a month or two. Surely the release could’ve been delayed a little, right?

Yes, but a little and another little and a third little turned into a lot and the fact is that Java 9 is released about a year later than originally planned, which was already half a year later than the two-year rhythm. So this approach clearly didn’t work well.

Mark Reinhold’s current proposal doubles down on the purely time-based releases, but shortens it from two years to six months. Yes, you got that right, a new “major” Java version (called feature releases) every six months! The underlying idea is that missing a release is not that much of a problem for a feature — the next one is always just around the corner.

Feedback on this has been overwhelmingly positive and I am thrilled as well. Getting new features every six months means that we no longer have to wait years for a finished feature to be released — instead we can start using it a few months after it’s done. It will also shorten the feedback cycle on a feature’s perception and impact.

Relevant in this context is a mechanism that was introduced by the module system: incubator modules. It allows the publication of APIs without standardizing them and we have to use --add-modules to make them available to our projects. This gives the JDK team leeway to introduce "beta APIs" and sits well with a fast release cycle.

Version Scheme

To make it easy to pinpoint when a version was released, Reinhold proposes to no longer use semantic versioning, but year.month, making Java 9's successor Java 18.3 (for March 2018).

Qualms with the new scheme

This one I’m not so sure about. There has already been some pushback on the mailing list and on Twitter and I tend to agree. I really don’t care much in which year a release was made and even less about the month.

One problem with year.month is that it looks like semantic versioning but isn't - 18.9 might have more severe changes than 19.3, yet the latter incremented the "major version", while the former did not. And it not only looks like semver, the new Java 9 API even claims it is.

Also, every newcomer has to be taught about this, so they don’t go looking for 18.4. And heavens forbid one release is not on time, so there’s a 18.4 after all. Or the release months change because nobody works over the summer, so x.9 never had any interesting new features. (At least that would reestablish semantic versioning.)

Then there’s the risk of polluting the “version space” with artificially high numbers. Java already changed the version schema a few times, most recently on September 21st which is still in the future, so it sounds unrealistic to assume that this change is the last. But there’s no way but forward from 20.3 — you can hardly go back to 13, explain to your users why that’s better than 20.3 and then at some point awkwardly jump from 17 over 18.3–20.3 and continue with 21.

No, I don’t think that’s a good idea.

Alternative proposals

Why not stick to the current scheme and increment the minor version with every feature release unless it contains considerable language/JVM changes, in which case the major version gets bumped.

To pick a few examples from history, Java 6 and 7 might have been 5.1 and 5.2 and, leaving the module system aside, Java 9 could have been Java 8.1 because the few language changes don’t require the bump to 9. Examples for major upcoming language changes would be generic specialization and value types from Project Valhalla. Amber’s proposals, on the other hand, could be seen on either side — I’d file enhanced enums and lambda leftovers under minor changes whereas local variable type inference, pattern matching, and data classes constitute major ones.

This would of course lead to discussions about how much impact a language change might have and whether it deserves a major version bump or not, but I don’t see any problems with that — the expected impact of a feature and how much it would change the code we write are already being discussed extensively anyways.

If all that’s no good and the year needs to be in there, I have a final suggestion: Go with year.increment (18.1, 18.2, ...) like JetBrains does for IntelliJ et al. This would give more leeway for adding, omitting, or rescheduling releases or the entire release schedule without baking that into the version.

Long-term support

To appease slower moving customers, Oracle would make every sixth feature release (so one every three years) a long-term support version that gets updates for at least three more years, whereas other feature releases are only updated for six months before users would have to jump to the next version to keep getting security updates.

I can’t really comment on this because I’ve never worked in an enterprise environment and hence don’t know the particular requirements and challenges very well.

Branching

If you’re interested in how the JDK team might implement these release trains on the technical side, check out Mark Reinhold’s proposal on the JDK mailing list. The summary is that the process will be heavy on feature and release branches with a main development line that is always close to shippable. Features are developed in branches and only merged once they’re (almost) done. Three months before a release a branch is created for it to stabilize features.

If you’ve tried Java 9 early on, you noticed that for the longest time there have been two EA builds: One “regular” and one “Jigsaw”. Since new features will not show up in the main line until development is almost done, I assume that this will become the norm to test them out while they’re under development. I expect there to be a build for Valhalla, another for Amber, another for Panama, and so on.

While that’s conceptually appealing, I already know I’ll dislike having a dozen JDK installs lying around that I have to switch between to experiment with new features. I also wonder how tool vendors will incorporate this when offering experimental support for upcoming features. Otherwise I think this is a very promising approach.

New challenges for content creators

This is kind of a weird aside, but writing a book that is still called The Java 9 Module System (we’re gonna change that soon), I have first-hand experience with some of the problems the faster cycles will cause for content creators.

Up to now, a new major Java version was relevant for about a year before its release, the two to three years during which it was the current version and then maybe another year or two before everybody moved on. That means you had about five years to tag blog posts, publish books, name courses, give talks, hold webinars, … for “Java X”. That made it very straightforward to name and market your content: Just put the version in there and everybody knows what it’s about.

This will have to change for various reasons:

  • a feature release is relevant for at most a year (six months where it’s current plus a few before and after)
  • nobody really knows what’s in it until three months before the release when all JEPs are targeted and the release branch is created
  • few people are going to remember in which exact version a feature was introduced

First of all, much content is created much too leisurely to keep up with this schedule. By the time a paper book on “X.Y” comes out, Java has moved on.

More importantly, the versioning scheme greatly diminishes the use of putting “Java X.Y” into titles for posts, books, etc. and that’s not just a marketing problem for profiteers. It also makes it harder for developers to learn about changes — no longer can you simply get your favorite publisher’s book on “Java X” or google for a few blog posts or a good online course and be confident that you’ve covered all your bases.

This means the community needs to develop a new way of thinking about Java, its development, and how the wider community teaches and learns about changes and improvements. (Also, now nobody will ever get a golden StackOverflow badge for Java releases beyond 9 anymore. Sad.)

One way I see is that we might move away from focusing on versions and instead follow the individual projects like Lambda, Jigsaw, Amber, Panama, Valhalla, etc. If there’s a project that interest you, look for sources on that, keep as up to date as your bandwidth allows and track which version it makes it into. This would actually get the community much closer to Java’s development, increase the chance of early feedback and maybe even contributions, so I think this would be an unexpected benefit — if we can pull it off.

In the meantime there is still value in sources that compile existing content on the various projects that made it into a specific release.


Licensing, commercial features, and standalone architecture

Wow, the comment on the release cadence got much longer than expected (surprise!), so I’ll leave you with a few sources and quotes on the other topics. Maybe I’ll expand on them over the next weeks.

Sources

InfoQ also wrote an article but it contains some severe misunderstandings, so better not read it.

Licensing

From Faster and Easier Use and Redistribution of Java SE:

Oracle plans to ship OpenJDK builds to make it easier for developers to deploy Java applications to cloud environments. We will initially offer Linux x64 binaries and add macOS and Windows later. These will be licensed under the GPLv2 with the “Classpath Exception”, allowing developers to easily and freely distribute them with their frameworks and applications.

From Java: Free At Last:

Which means that Java will finally be freed of the explicit and implicit field of use restrictions which have dogged it since its invention. Developers will be free to use Java on any device, without requiring any additional licensing or other permission. I believe that this is going to lead to a resurgence of innovation in the Java ecosystem. And I am particularly optimistic about what this could mean for Java as the language of choice for many solutions in the Internet of Things.
[…]
A little over a decade ago, Sun Microsystems started the process of open sourcing Java. It seems that Oracle is finally finishing the job. Good for them.

Commercial features

From Faster and Easier Use and Redistribution of Java SE:

Oracle will also open source commercial features such as Java Flight Recorder previously only available in the Oracle JDK. We plan to open source a number of additional internal development projects after proposing and discussing with OpenJDK contributors.

Martijn Verburg’s comment on the mailing list:

As for the open sourcing of items like JFR and Mission Control — that’s going to be a huge boost to the ecosystem in terms of debug and performance tuning not to mention everything else, so thank you (and to the other Oracle folks who helped make this decision)!

Great, reduces divergence between Oracle JDK and OpenJDK!

Standalone architecture

From Faster and Easier Use and Redistribution of Java SE:

As client application development continues to shift from the old “plugin” world to modern deployment, the need for a standalone Java Runtime Environment (JRE) that is installed centrally, separately from Java applications has diminished. Using the ‘jlink’ tool introduced with JDK 9 will make it even easier for application developers to package and deploy dedicated runtimes rather than relying on a pre-installed system JRE. Oracle will begin transitioning from the standalone architecture later next year in what will be a multi-year effort.

Sounds like Oracle assumes applications will mostly package the JRE modules they need and thus become self-sufficient, obviating the need for installed JREs. Wow!

so long … Nicolai


PS: Don’t forget to subscribe or recommend! :)