Hey everyone,
As many of you know, we’re preparing to release a completely revamped OpenMRS Platform 3.0.0. This major update will modernize the OpenMRS Core, including a migration to Java 21 as the minimum required version, officially dropping support for older Java versions.
While the OpenMRS Core already compiles with Java 21, most of our community-supported modules are not yet compatible. Here’s a list of key modules that need to be evaluated and updated:
During the recent Platform meeting, it was proposed that instead of blindly migrating all these modules to Java 21, we should review each module individually and make thoughtful decisions:
Should we update the module to support Java 21?
Should we replace it with a more modern or robust alternative?
Should we deprecate the module and migrate its functionality into the OpenMRS Core or another supported module?
We’d love to hear your thoughts on this approach. If you have any suggestions or updates regarding these modules, please feel free to share.
FHIR2 has additional considerations, since it’s heavily dependent on HAPI, but we need to make some adjustments to be able to upgrade to a newer version of HAPI which may be necessary to support Java 9+.
There’s been some noise about completely re-doing the event module, but that hasn’t materialized. However, that embeds a (quite old) ActiveMQ server which may not work on a newer version of Java.
For the REST module, the biggest issue is whether or not we retain support for older versions (going back to 1.8) and, if so, what it means to “update” it to support Java 21 (this is fairly unique in that retaining back to 1.8 also requires a Java 7 baseline instead of Java 8).
I have some concerns regarding the XStream module. While working on the migration, I’ve been encountering test errors like the one below, caused by illegal reflective access:
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private transient java.util.NavigableMap java.util.TreeSet.m accessible: module java.base does not "opens java.util" to unnamed module @473b46c3
This happens because XStream relies on reflective access to internal JDK classes, which is restricted in modern Java versions. we can mitigate this issue using the JVM option --add-opens, I don’t think we should rely on such workarounds for Java 21 migrations.
@ibacher also raised similar concerns in TRUNK-6197.
Unfortunately, that type of reflective access necessary for how XStream works.
I’ve proposed a few times migrating from using XStream to something else like leveraging Jackson to support XML, but that requires a bit of careful attention to ensure we can deserialize things that have been serialized using XStream and the fact that we have multiple XStream serializers probably complicates things a bit too.
tl;dr: transition to Jackson & JSON without trying to support legacy data; create a module to help implementations make the transition
We discussed this a bit on today’s Platform Team call. The general sentiment was that we don’t want to bypass constraints that have been made for security purposes (i.e., adding the JVM option --add-opens is not a viable option). The best way forward seems to be to adopt a widely supported & active library (like Jackson) that can serialize to JSON with the goal of supporting 80% or more of serialization needs (i.e. most cases but not necessarily all the edge cases). Once we have a Jackson JSON-based solution, then we could create a script or module that can do the one-time task of helping an implementation translate Xstream-based XML entries in the database to Jackson-based JSON entries.
Oh! One reason I was looking at Jackson is because it’s capable of serializing and deserializing XML. I kind of hoped that (with appropriate code changes) we could continue to support already-serialized XML data. (Apologies, I had an interfering call or else I’d have been on the platform call).
It would be great if we could identify here the downstream dependencies on SXS - what modules / features are using this that we need to preserve.
The reporting module is likely the biggest user and the most complex, as the definitions that it serializes can basically have any arbitrary Java property.
One thing I’ve had in the back of my head for a while now is to see if we can simplify the reporting module a bit for the future in a new major version, which would remove all of the legacyui dependencies, and all of the serialization.xstream, htmlwidgets, and calculation dependences, and put these into one or more optional add-on modules, so that the reporting module API could be leveraged without as much dependency baggage. This may be something to consider within this initiative.