Spring Boot 2 to Spring Boot 3: The Complete Migration Guide for Enterprise Java
Why Spring Boot 2 to 3 Is Not a Minor Version Bump
Spring Boot 3.0 was the most consequential release in Spring's history in terms of breaking changes. Three changes drive almost all the migration complexity: the minimum Java version increased from Java 8 to Java 17, the foundation shifted from Java EE to Jakarta EE 10 (with the javax.* to jakarta.* namespace change), and Spring Security 6.x introduced a revised security model that deprecated large parts of the 5.x configuration API. An application that compiles clean against Spring Boot 2.7 will not compile against Spring Boot 3.0 without changes; in complex applications, the migration scope can touch hundreds of files.
Prerequisites Before Starting
Before beginning the Spring Boot 3 migration, confirm that your environment meets the prerequisites:
- Java 17 or later: Spring Boot 3 requires Java 17 as the minimum. If your organisation is running Java 11 or Java 8, the JVM upgrade is a prerequisite — one that itself requires compatibility testing and may require changes to your deployment pipeline.
- Third-party library compatibility: Any library in your dependency graph that has Spring Framework or Java EE as a transitive dependency may need to be upgraded to a Jakarta-compatible version. This includes persistence libraries (Hibernate 6 for Spring Boot 3), testing frameworks, and any custom Spring integrations.
- Spring Security 5.8.x migration first: The Spring team recommends migrating to Spring Security 5.8.x before upgrading to Spring Boot 3. Spring Security 5.8 included the deprecation bridge that makes the Spring Security 6 changes more manageable.
The javax.* to jakarta.* Namespace Migration
This is the most mechanically extensive part of the Spring Boot 3 migration. Jakarta EE 10 renamed all Java EE APIs from the javax.* namespace to jakarta.*. Every import statement, annotation, and configuration file that references a Java EE API must be updated. In practice this affects:
- Servlet API usage:
javax.servlet.*→jakarta.servlet.* - JPA entities and repositories:
javax.persistence.*→jakarta.persistence.* - Bean Validation:
javax.validation.*→jakarta.validation.* - JAX-RS / JAX-WS clients:
javax.ws.rs.*→jakarta.ws.rs.* - Mail:
javax.mail.*→jakarta.mail.*
The OpenRewrite project provides an automated migration recipe (org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0) that handles the bulk of the namespace migration as a series of AST transformations. Running this recipe will address most mechanical renames; the residual issues are the ones where logic depends on API behaviour that changed, not just renamed.
Spring Security 6 Breaking Changes
Spring Security 6 removed several deprecated configuration patterns that were common in Spring Boot 2.x applications:
WebSecurityConfigurerAdapterwas removed. Security configuration must use the component-based approach introduced in Spring Security 5.7.HttpSecurity.antMatchers()and related methods were replaced byHttpSecurity.requestMatchers().- Password encoding via deprecated
NoOpPasswordEncoderis not allowed without explicit configuration. - OAuth2 client and resource server configurations changed significantly in Spring Security 6.
Testing and Validation Strategy
The migration should proceed in stages, with a test gate at each stage:
- Compile all modules against Spring Boot 3 dependencies — resolve compilation errors before attempting runtime testing.
- Run unit tests and fix failures from API behaviour changes (not just compile-time namespace issues).
- Run integration tests against a real Spring application context — many Spring Boot autoconfiguration changes only surface at runtime.
- Run end-to-end tests against a staging environment with Spring Boot 3 — focus on authentication flows, transaction management, and any code that relies on Spring internals.
OSSeva Spring Continuation Support
For applications that cannot complete the Spring Boot 3 migration before Spring Boot 2.7's EOL date, OSSeva provides extended CVE patching for Spring Framework 5.3.x, Spring Boot 2.7.x, and Spring Security 5.8.x. This covers the security gap during the migration window without requiring a rushed upgrade under compliance pressure.
Conclusion
The Spring Boot 2 to 3 migration is achievable but scope-intensive. The namespace change and Spring Security refactor are the two highest-effort components; OpenRewrite automation addresses most of the mechanical namespace work. The organisations that manage this migration cleanly are the ones that stage it carefully, run automated migration recipes before attempting manual fixes, and maintain the Spring Boot 2.7 branch under extended security support during the transition period.
Tags