Upgrading from JavaEE to JakartaEE using OpenRewrite

Posted by Joep Weijers on April 26, 2023

In our software, we have transitive dependencies on code from Java’s Enterprise Edition (JavaEE). The code is typically in javax.* packages. The owner of Java, Oracle, opensourced the JavaEE specification and has donated it to the Eclipse foundation. This however came with one very impacting condition: that the trademarked Java name is no longer used in the specifications. The specification rename to JakartaEE was pretty easy. Renaming all the packages to jakarta.* was not. This means that all code depending on JakartaEE has to be updated to use the new packages. Although some libraries manage to handle both javax.* and jakarta.* packages at the same time, you really only want to have only one of them. That also means that all libraries that you use have to be updated to use jakarta.* packages before you can successfully update your own code. Here is how we did it:

The upgrade path to JakartaEE

By now most libraries provide a JakartaEE version with updated package names, so we can update our own projects. We recommend to do the upgrade in three steps:

  1. Ensure you are on the latest JavaEE version of a dependency.
  2. Update the reference of the dependency to its JakartaEE version, with the same version. For example: instead of the javax.activation:activation-api:1.2.0 artifact, use jakarta.activation:activation-api:1.2.1. This new artifact still uses the javax.* packages, so this change should not have any impact on your code.
    Ensure to only have one and not both of the artifacts or you may find duplicate classes at runtime. Which is fine as long as the classes have the same contents, but can lead to runtime issues when they are not.
  3. Do the major version update of the dependency. With the previous examples: start using jakarta.activation:activation-api:2.1.1. This will bring in the jakarta.* packages, so you need to update all references in your code and configuration from javax.* to jakarta.*. Note that you probably have to update all your dependencies at once.

Tool assistance

There are tools available to aid you in step 3. One example is OpenRewrite, which has a set of recipes that modifies your build file to use the correct JakartaEE artifacts and updates any references in your code. You can execute the rewrite in your Maven project by executing the following command in your project:

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:LATEST -Drewrite.activeRecipes=org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta

The OpenRewrite plugin will list all files it modified and what it changed:

[INFO] ----------< com.topdesk.reporting-layer:reporting-layer-main >----------
[INFO] Building Reporting Layer main 0.1-SNAPSHOT                         [5/6]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] >>> rewrite-maven-plugin:4.45.0:run (default-cli) > compile @ reporting-layer-main >>>
[INFO] Validating active recipes...
[INFO] Project [Reporting Layer] Resolving Poms...
[INFO] Project [Reporting Layer main] Parsing source files
[INFO] Running recipe(s)...
[WARNING] Changes have been made to reporting-layer-main\pom.xml by:
[WARNING]     org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta
[WARNING]         org.openrewrite.java.migrate.jakarta.JacksonJavaxToJakarta
[WARNING]             org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId: {oldGroupId=com.fasterxml.jackson.jaxrs, oldArtifactId=jackson-jaxrs-json-provider, newGroupId=com.fasterxml.jackson.jakarta.rs, newArtifactId=jackson-jakarta-rs-json-provider, newVersion=2.13.x}
[WARNING]         org.openrewrite.java.migrate.jakarta.RestAssuredJavaxToJakarta
[WARNING]             org.openrewrite.maven.UpgradeDependencyVersion: {groupId=io.rest-assured, artifactId=*, newVersion=5.1.x}
[WARNING] Changes have been made to reporting-layer-main\src\main\java\com\topdesk\devreportinglayer\main\DevApplication.java by:
[WARNING]     org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta
[WARNING]         org.openrewrite.java.migrate.jakarta.JavaxWsToJakartaWs
[WARNING]             org.openrewrite.java.ChangePackage: {oldPackageName=javax.ws, newPackageName=jakarta.ws, recursive=true}

In your Source Code Management system you can see the differences:

Modification from javax to jakarta made by OpenRewrite
Modification from javax to jakarta made by OpenRewrite

While OpenRewrite is powerful, you still have to test. Many JakartaEE classes are using the Java Service Provider interface, annotations with textual references to classes or configuration in XML files. So it is wise to do a search through your entire code base for any remaining occurrences of javax. Any issues in configuration could only present themselves at runtime of your application!

About the author: Joep Weijers

Joep is a Developer Experience Engineer at TOPdesk with a keen interest in delivering quality software continuously. He loves playing around with Jenkins Pipelines, GitLab CI, Selenium, Docker, Kubernetes and keeps in touch with his inner developer by educating his colleagues on testable Java code.

More Posts - Website