Back to blog

// OSSeva Blog

Migration

javax to jakarta Migration: A Practical Guide for Spring Boot 2 to 3

Randall McClure7 min read

The short answer

The javax to jakarta migration is a package rename. Up to Java EE 8 the enterprise APIs lived under the javax prefix. Jakarta EE 9, released on 8 December 2020, moved them all to jakarta. Spring Framework 6 requires Jakarta EE 9 or later and Spring Boot 3 builds on it, so no upgrade from Spring Boot 2 to 3 skips this step. Spring Boot 3.0 also requires Java 17, and chose Jakarta EE 10 compatible dependencies wherever it could.

The rename is mechanical, and tools do most of it. The real work is the dependency tree. Every library that touches a servlet, an entity or a validator also needs a release built for the new namespace.

Why the namespace changed

When Oracle handed Java EE to the Eclipse Foundation, the Java trademarks did not go with it. In May 2019 the Eclipse Foundation announced that the Jakarta EE community could use the old package names only as is, with no modifications. A specification that needed to evolve had to move. Jakarta EE 9 did it in one release, which the Eclipse Foundation called the big bang.

What changes, and what must not

Only packages that belonged to Java EE move. These are the ones Spring applications meet most often:

javax.servlet      -> jakarta.servlet
javax.persistence  -> jakarta.persistence
javax.validation   -> jakarta.validation
javax.annotation   -> jakarta.annotation   (@PostConstruct, @PreDestroy)
javax.transaction  -> jakarta.transaction  (@Transactional, JTA)
javax.ws.rs        -> jakarta.ws.rs
javax.xml.bind     -> jakarta.xml.bind
javax.mail         -> jakarta.mail
javax.jms          -> jakarta.jms

# Part of Java SE: these stay exactly as they are
javax.sql  javax.crypto  javax.net.ssl  javax.transaction.xa
javax.annotation.processing  javax.xml.parsers (and the rest of JAXP)

The second group ships with the JDK and is never renamed. This is why a blind find-and-replace breaks the build: it rewrites JDK imports that were already correct. Two prefixes need extra care because they hold both kinds, the transaction packages and the XML packages.

Tools that do the rename

OpenRewrite

For a Spring application, use the Spring Boot 3 recipe rather than the bare namespace recipe. org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0 in rewrite-spring chains the Spring Framework 6 migration (which includes the rename), the Spring Security 6 migration and the move to Java 17. For a plain Jakarta EE project, org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta in rewrite-migrate-java does the rename alone. From the command line:

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
  -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE \
  -Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0

IntelliJ IDEA

IntelliJ IDEA Ultimate has Refactor | Migrate Packages and Classes | Java EE to Jakarta EE. It shows a preview before it changes anything and knows which packages belong to Java SE.

Eclipse Transformer and the Tomcat migration tool

Both work on byte code, not source code. The Eclipse Transformer rewrites class files and archives (JAR, WAR, EAR), which helps with a dependency you cannot rebuild. The Apache Tomcat Migration Tool for Jakarta EE converts a Java EE 8 web application built for Tomcat 9 so it runs on Tomcat 10 or later: java -jar jakartaee-migration-*-shaded.jar <source> <destination>. Check that third-party licences allow modified copies before you ship converted artifacts.

The dependency audit is the real work

  • Find every old artifact. In Maven, run mvn dependency:tree and look for the old servlet, persistence and validation API artifacts. Each needs a Jakarta replacement.
  • Third-party libraries. Some publish a separate Jakarta artifact, some switched in a new major version, and a few never moved. The last group decides your timeline.
  • Hibernate 6. Spring Boot 3.0 uses Hibernate 6.1, which is based only on jakarta.persistence. Hibernate 6 also changes query and type handling, so test the persistence layer, not just the build.
  • Spring Security 6. WebSecurityConfigurerAdapter is gone and antMatchers gives way to requestMatchers. Spring recommends upgrading to Spring Security 5.8 first.
  • The application server. A WAR on an external Tomcat 9 or another Java EE 8 application server will not run once it imports jakarta classes. It needs Tomcat 10.1 or a Jakarta EE 10 server.

A sequence that works

  1. Upgrade to the latest Spring Boot 2.7.x. Spring Boot 2.7.18 runs on Java 8 up to Java 21, so you can move to Java 17 here and separate JVM problems from namespace problems.
  2. Move to Spring Security 5.8 and clear its deprecations.
  3. Run the OpenRewrite Spring Boot 3 recipe on a branch and review the diff.
  4. Add spring-boot-properties-migrator to list properties you need to configure under new names, then remove it.
  5. Test web behaviour: a trailing slash no longer matches by default, so /greeting/ now returns 404.

When the migration outlasts the support window

Spring Boot 2.7 open source support ended on 30 June 2023 and Spring Framework 5.3 open source support ended on 31 August 2024. Broadcom's commercial support for both runs to 30 June 2029. OSSeva's Spring continuation support patches Spring Boot 2.7 and Spring Framework 5.3 while the rename proceeds; the Spring Boot 2 end-of-life page and Spring Framework 5 end-of-life page set out the dates, and our Spring Boot 2 to 3 migration guide covers the wider upgrade.

Frequently asked questions

What is the difference between javax and jakarta?

The package name is the main difference. The rename was the headline change in Jakarta EE 9, and later Jakarta EE releases added new features on top.

Does Java 17 use javax or jakarta?

Java SE 17 itself still uses its own packages such as javax.sql and javax.crypto. The enterprise APIs are not part of Java SE; on Java 17 you choose them through your dependencies, and Spring Boot 3 chooses jakarta.

Can a javax library run inside a Spring Boot 3 application?

Only if it never touches Jakarta EE types. A library that implements a servlet filter or a JPA entity against the old package will fail at runtime. Upgrade it, or convert its byte code with the Eclipse Transformer as a stopgap.

Is there an Apache Tomcat migration tool for Jakarta EE?

Yes. The Apache Tomcat Migration Tool for Jakarta EE converts a Java EE 8 web application so that it runs on Tomcat 10 or later.

Tags

Spring BootJakarta EEJavaMigrationOpenRewrite

Ready to get your open source under control?

Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.