Moving OpenMRS beyond Java 8

It has been more than a year since Java 8’s end of life. While there is still extended support for a few more years and OpenJDK 8 (extended) support continues until Nov 2026, environments are going to continue dropping support for Java 8 and it is going to become increasingly more difficult to do development in Java 8.

As a community, can we start thinking about moving beyond Java 8?

  • What would this mean for implementations?
    • What Java runtimes are implementations using now. Are the majority still using Java 8? Or Java 11?
    • Are there implementations that are unable to migrate to Java 11+ for their runtime environment?
  • What would this mean for developers?
    • Are there key/popular modules that require Java 8 SDK for development?
    • Could we use one of these modules along with core/platform to identify the work needed to migrate from Java 8 to Java 11?

As a community, it a reasonable target could be:

  • We all agree on a Java LTS version on which OpenMRS code is expected to run.
    • For example, if we agree this should be an LTS that’s ~3-5 years old, that would mean changing from Java 8 to Java 11
    • OpenMRS & modules are built (by default) using this version of Java
  • Developers can develop using the more recent version of Java (e.g., Java 17…even Java 21 later in 2023), using --release to compile for the supported version.

It’s obviously critical that we make choices like this in a way that minimizes disruption for implementations and still allows us as a community to avoid inheriting undue risks & challenges of using legacy frameworks.

Thoughts?

/cc @dkayiwa

7 Likes

Thanks for starting this conversation @burke . I definitely makes sense for us to plan and encourage these upgrades. At PIH, we are on Java 8 everywhere still AFAIK, though I don’t believe there are any known roadblocks to upgrading, other than full confidence that our OpenMRS distributions(s) - generally running in a 2.5.x environment - fully support Java 11 and prioritizing making the switch.

It will be good to hear from others who have already successfully made the switch to Java 11 (possibly in conjunction with upgrading to a later version of Tomcat).

Great idea @burke ! And yes tomcat too possibly as @mseaton suggested , you would think tomcat 10.1.x which would require upgrading the servlet API version to 6

While I don’t have a lot of concrete implementations to report on, this is something I’ve thought about a fair bit.

From a JDK version support perspective, Oracle has been doing an absolutely awful job of keeping to a predictable LTS support. Initially, when Java 9 was released, the release cycle was supposed to be something like “a new version every 6 months and every third release is an LTS release; each LTS release supported for 6 years.” While the Java project has been consistent about the “a new version every 6 months”, LTS support has been much more haphazard (the current LTS versions are 8, 11, and 17; the next projected LTS is 21—but so far only one LTS has happened on this projected schedule).

A further complication to this is that because of the introduction of the Java Module system—specifically, its encapsulation features and the use of these to “freeze off” parts of the runtime core—Java 8 currently has a later guaranteed support date (2030) than either Java 11 or Java 17.

All of that is to say, that predicting what versions of Java we should support has become a bit of a mess…

That said, current state:

  • Core 2.4.0+ supports Java 8 and Java 11
  • RefApp modules that support core 2.4.0+ support Java 11 at runtime
  • Core doesn’t work on Java 17 yet (there’s this issue, but also we’re using Spring 5, which officially supports Java 8 and Java 11)

Looking ahead:

  • More libraries are increasingly requiring Java 11 as a minimum, so it would probably make sense to adopt that as our minimum version at some point in the not-too-distant future.
  • Spring 6 requires Java 17
  • Supporting Servlet API 6 will require Spring 6 (because of the renaming of javax.servlet → jakarta.servlet) and consequently, migrating to Java 17 as a minimum version

Most modules that have been updated to run on Core 2.4.0 should be relatively straight-forward to update to support Java 11 for development, but (because our core releases are tied to Spring versions) this likely means that those modules will need to be built to target Core 2.4.0 as a minimum version. Basically, it maintaining support for older versions of Core that leaves our modules pinned to Java 8. Conceptually, we can retarget the version of Core required by those modules and bump them up a major version, maintaining the version targetting pre-Core 2.4.0 as a separate branch.

Unfortunately, until Java stops sealing-off parts of the JDK, I don’t think we can make this guarantee (AFAIK, from Java 17+, this hasn’t been a problem, but I don’t think we’re in a place were we can easily adopt Java 17 as a minimum yet).

1 Like