Skip to content

ADR 3 Java update strategy beyond Java 8

Joel Håkansson edited this page Apr 14, 2019 · 1 revision

Date: 2018-02-08
Status: Accepted

Decision

The java update strategy going forward is this:

  • Whenever a new Java version becomes publicly available, use it for subsequent builds and releases, if possible
  • Don't change the major version number for components based on JDK version
  • Distribute the latest Java runtime with the application

Rationale

Over the years the Java community has been spoiled with excellent backwards compatibility. I can run my 2005 project on Java 8 without recompiling. Now compare this with other platforms. For example, pretty much every major iOS release has introduced compiler errors and broken already compiled and deployed code.

Starting with Java 9, the release schedule for Java has changed from a fixed feature frame to a fixed time frame. This inevitably changes how we plan our own releases.

Up until now, many software projects have supported older java versions for a long time, perhaps even longer than Oracle/Sun themselves have. In addition, it has been a common practice to change the major version number of components when they are built using a new major version of the JDK. As far as I can tell, semantic versioning doesn't require this. Keeping a component's major version tied to a major version of the JDK has been feasible up until now, to a large extent because of the comparatively slow update cycle. And it does have some advantages. However, this becomes problematic in the light of the new six month release cycle for the Java platform. The minimum java version requirements of a project's dependencies are likely to diverge quickly. Some may introduce a policy to only use the LTS versions (11 and 17 and so on), but some will update based on other criteria. This has always been the case, but because the time between releases is much shorter, the problem becomes bigger. The reactive approach - stay on a release until forced to upgrade - may not work so well in the future.

A more reasonable approach would be to always support the current version of the Java platform. Even Oracle doesn't make any commitments to the non-LTS releases beyond the six months within which it is the current version. This may seem problematic, and while it could be, it might not be that big of a deal. For one, the releases will contain fewer changes, so adapting to a new version will be easier and quicker than before. Yes, there's a risk of depending on artifacts that contain APIs that have been removed in the current version. This is something that we never had to worry about in the past, because no APIs were ever removed from Java before the release of Java 9. But removal of APIs can happen in every single artifact a project depends on. Staying on an older version for this reason alone is rarely a good idea. Instead, you fix the problems and move forward.

What about environments that can't be updated to the latest version? Well, as Oracle is also moving away from Java Webstart, the message is clear: Don't rely on a Java runtime being installed on the system, distribute the Java runtime with the application. The addition of Jlink also pushes in this direction by allowing customization of the Java runtime to the specific needs of a single application. The insight that end users are not going to keep up with the six month cycle has perhaps contributed to this change in direction. In any case, distributing a matching Java runtime with the application seems like the only viable option if the environment cannot be controlled.*

*As of 2018-11-13, this is blocked by the removal of javapackager in Java 11, see http://openjdk.java.net/jeps/343

Clone this wiki locally