- How to upgrade to Jakarta EE 10 and GlassFish 7 – it’s much easier than you think!
- Upgrade to Jakarta EE 10 – part 1: Transform Applications with Eclipse Transformer
- Upgrade to Jakarta EE 10 – part 2: Transform Application Source Code
- Upgrade to Jakarta EE 10 – part 3: Transform incompatible Dependencies
In our previous article, we explored the initial steps of migrating Java EE 8 or Jakarta EE 8 applications to Jakarta EE 10. We transformed the final binary application using the Eclipse Transformer to deploy it on a Jakarta EE 10 runtime. Building upon that foundation, we now dive deeper into the next crucial phase of the upgrade process: transforming the application’s source code to use the Jakarta EE 10 APIs. This will enable you to use new features in Jakarta EE 10 as well as newer versions of external libraries that require Jakarta EE 10.
Why do we need tools to migrate from “javax.” to “jakarta.” ?
Although most of the transformation involves replacing imported packages that start with the "javax.
” prefix by those that start with “jakarta.
” prefix, the whole transformation is not that simple. For example, not all packages with the “javax.
” prefix should be transformed, resource files like XML descriptors also need to be transformed, etc. Since Jakarta EE 10 also removed some deprecated APIs, mainly in Jakarta Faces (JSF), source code that uses the removed APIs needs to be refactored to use newer Jakarta EE APIs.
Fortunately, we can automate most of the work to upgrade to Jakarta EE 10. There are 2 free tools that can help us here:
- OpenRewrite – a tool that can automatically make changes to your application’s source code based on specified rules. It contains rules for Jakarta EE 9 and 10.
- Eclipse Transformer – we used it earlier to transform the final application to Jakarta EE 9 but it’s also capable of transforming Java source files and resources
We recommend using both tools – first use OpenRewrite, and then Eclipse Transformer to run additional transformations. OpenRewrite provides most of the necessary transformations, and it can also upgrade some widely used libraries to a version compatible with Jakarta EE 10. However, it still misses some transformations, which Eclipse Transformer can do. Therefore you get the best result if you combine them, in the suggested order – OpenRewrite first, Transformer second.
UPDATE: As both OpenRewrite and Transformer were updated and received some new transformation rules, we also updated this guide to match that and describe how to get the best transformation result based on our experience. Compared to the previous version of our guide, we now recommend running OpenRewrite before Eclipse Transformer, to avoid some manual steps, which are needed if they are used in a different order.
Automate source code changes with OpenRewrite
Applying OpenRewrite is very easy. If you already have Maven installed, you can just use it as a Maven plugin configured on command line:
- Go to the application’s project directory
- Execute the following command:
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.JakartaEE10
This will modify your application in-place.
Further source code transformations with Eclipse Transformer
We will now use Eclipse Transformer to apply some code transformation that OpenRewrite might have missed. From our experience, it’s mostly textual values in some Java annotations or in XML files. Follow these steps to transform source code of your application using Transformer:
- Download Eclipse Transformer CLI distribution artifact from Maven Central. Download the
distribution.jar
file of the latest version, not the plainjar
file. For the version 1.0.0, here’s the direct download link: org.eclipse.transformer.cli-1.0.0-distribution.jar - Unpack the JAR file into some directory, e.g.
/path/to/transformer
- Go to you application’s project directory
- Run the following to transform the
src
directory (with source code, resources, test code and resources, etc…) tooutput_src
directory:java -jar /path/to/transformer/org.eclipse.transformer.cli-1.0.0.jar src
- Move the contents of the
output_src
directory intosrc
(overwrite files). On Linux and Mac OS, you can use RSync command line tool:rsync -a output_src/* src
After performing these steps, your application source code should be completely compatible with Jakarta EE 10. You can try to build your application now. If your application does not contain any dependencies incompatible with Jakarta EE 10, it should compile successfully and work well if you deploy it on a Jakarta EE 10 server like GlassFish 7
What you can’t automate (yet)
After applying all the automation described in this or in the previous articles, there are still some things to do, which can’t be automated with existing tools:
- Deal with external libraries that require Java EE 8 or Jakarta EE 8 APIs
- Refactor code that uses APIs removed in Jakarta EE 10 if it wasn’t transformed by OpenRewrite
Sorting out dependencies is very crucial because they often provide non-trivial functionality and their code isn’t under our control. If the application doesn’t require such library at compile time, we can simple apply Eclipse Transformer on the final binary (e.g. WAR file) as described in the previous article and then deploy the application on a Jakarta EE 10 runtime. But if some libraries are required to compile the application, the compilation would fail after we transform the source code because of the change in the package prefix. We have several options to fix that:
- Upgrade the library to a newer version, if it supports Jakarta EE 10 – this can be partially automated by OpenRewrite for some well known libraries
- Transform the library with Eclipse Transformer into a new Maven artifact, which our application will use instead
- Replace the library with some other similar library that supports Jakarta EE 10 and refactor our application to use that library instead
The simplest way is to upgrade the library. Nowadays, new versions of many popular libraries either switched to Jakarta EE 10 or provide a variant of the library that requires Jakarta EE 10. As an example, a very popular library Primefaces provides a Jakarta EE 10 Maven artifact under the “jakarta
” classifier, as an alternative to the main artifact that requires Jakarta EE 8. You can use the Jakarta EE 10 variant with the following Maven dependency definition:
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>12.0.0</version>
<classifier>jakarta</classifier>
</dependency>
Note that OpenRewrite, with the latest transformation recipes, does this for you and updates dependency definitions for Primefaces and some other dependencies it recognizes.
Transforming a library with Eclipse Transformer is more complicated to set up in your project but may be required if the library doesn’t support Jakarta EE 10 or you’d like to postpone upgrading that library because it’s too risky.
In the future articles, we’ll provide a list of popular libraries that already support Jakarta EE 10 and how to add them to your project. We’ll also explain how to transform dependencies so that their transformed versions are available during compile time. And we’ll also explain how to deal with the breaking changes in Jakarta EE 10, which removed some obsoleted APIs.
Conclusion
Migrating your Java EE 8 or Jakarta EE 8 applications to Jakarta EE 10 involves not only transforming the final binary application but also updating the application’s source code to utilize the Jakarta EE 10 APIs. This enables you to leverage new features and ensure compatibility with external libraries that require Jakarta EE 10.
As we explained, it’s not only about replacing those old “javax.
” packages with new “jakarta.
” ones. Though, we can automate this to speed up this task and avoid manual errors.
There are 2 tools to automate the migration – OpenRewrite and Eclipse Transformer. Both contain some unique rules not contained in the other tool, so you get the best result if you use both. First, OpenRewrite will update the source code and your project build file to upgrade the dependencies. Then, Transformer will apply additional transformations that OpenRewrite may have missed.