How to Upgrade Spring Boot 2.x to 3.x: Key Pitfalls, Jakarta EE Migration, and Best Practices
This guide explains the major changes when moving from Spring Boot 2.x to 3.x, covering JDK requirements, full Jakarta EE package renaming, third‑party library compatibility, Spring Security redesign, configuration adjustments, testing updates, new features, and step‑by‑step migration recommendations.
Overview
Spring Boot 3.x is built on Spring Framework 6 and Jakarta EE 10, requiring JDK 17+ and causing package name changes from javax.* to jakarta.*. Migration involves updating the JDK, dependencies, configuration files, and source code.
JDK Requirements
Minimum JDK version: 17 (JDK 21 LTS is recommended).
Projects running on JDK 8 or 11 must upgrade to JDK 17 before migrating.
Jakarta EE Package Migration
All javax.* packages become jakarta.*. Typical impact areas:
Servlet API: javax.servlet → jakarta.servlet JPA: javax.persistence → jakarta.persistence Bean Validation: javax.validation → jakarta.validation Update source code, Maven/Gradle dependencies, and third‑party libraries to use the new package names; otherwise compilation fails.
Old libraries (e.g., early versions of Hibernate Validator, Shiro, MyBatis extensions) must be upgraded to versions that support Jakarta packages.
Third‑Party Dependency Compatibility
Dependencies must support Spring 6, Jakarta EE 10, and JDK 17. Key areas to verify:
Security frameworks (Spring Security, Shiro)
ORMs (Hibernate, MyBatis, JOOQ)
Template engines (Thymeleaf, Freemarker)
API documentation – replace Swagger 2 with springdoc-openapi (Swagger 2 is no longer maintained and is incompatible).
Spring Security Changes
Package Import Replacement
Replace all javax.* imports with the corresponding jakarta.* imports (IDE bulk‑replace is useful).
Configuration Redesign
Remove the WebSecurityConfigurerAdapter subclass.
Add a SecurityFilterChain bean using the lambda DSL:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated());
return http.build();
}JPA and Hibernate Adjustments
Update the namespace in persistence.xml if present.
Change the dialect class name to the new Hibernate 6 package.
Review Hibernate 6 API changes, especially stricter @Formula syntax and JPQL queries.
Configuration Property Changes
Property names have been renamed or deprecated, e.g., spring.data.rest.basePath → spring.data.rest.base-path, and spring.jpa.hibernate.use-new-id-generator-mappings is removed.
Re‑confirm Actuator endpoint exposure configuration:
management:
endpoints:
web:
exposure:
include: "*"Testing Framework Updates
Switch to JUnit 5.
Replace @RunWith(SpringRunner.class) with @ExtendWith(SpringExtension.class).
Add Maven dependency for JUnit 5:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.x.x</version>
<scope>test</scope>
</dependency>Internationalization (i18n) Default Encoding
MessageSourcenow defaults to UTF‑8 (previously ISO‑8859‑1). Verify the encoding of .properties files in legacy projects.
Hibernate 6.x Changes
Hibernate 6.x is the default JPA provider for Spring Boot 3.x.
API changes include adjusted Query#unwrap behavior, stricter @Formula syntax, and new dialect package names.
SQL parameter binding defaults to position‑based binding.
Configuration Property Adjustments
Several properties have been renamed or removed; consult the Spring Boot 3.0 Migration Guide for a full comparison table.
New Features Highlights
Spring Framework 6 – full support for JDK 17+ language features (records, sealed classes, pattern matching) and native Virtual Threads (JDK 21 Project Loom).
Jakarta EE 10 – latest Servlet 6.0, JPA 3.1, Bean Validation 3.0.
AOT / Native Image – built‑in GraalVM Native Image support; build with mvn -Pnative native:compile for fast startup and low memory, ideal for microservices and serverless.
Observability – tighter integration with Micrometer and OpenTelemetry for tracing and metrics.
JSON handling – default Jackson 2.14+ with better support for Java 17 records and Instant; @JsonCreator simplifies deserialization.
Web layer improvements – performance gains for WebFlux and WebMvc; new declarative HTTP client using @HttpExchange:
@HttpExchange("/users")
interface UserClient {
@GetExchange("/{id}")
User getUser(@PathVariable String id);
}Docker/K8s support – spring-boot:build-image creates smaller container images; buildpacks automatically detect the runtime environment.
Upgrade Recommendations
Upgrade third‑party dependencies first (Spring Security, Hibernate, Thymeleaf, Swagger → springdoc-openapi).
Bulk replace package names ( javax → jakarta) in source code and XML descriptors.
Refactor security configuration to use SecurityFilterChain instead of WebSecurityConfigurerAdapter.
Run full integration tests, especially for persistence and i18n.
Optionally build a GraalVM native image to improve startup time.
Troubleshooting Steps
Compile‑time: missing imports, dependency version conflicts, API‑related compilation errors.
Startup‑time: Spring Security DSL errors, Hibernate entity scanning or mapping failures.
Runtime: Actuator endpoints inaccessible, missing monitoring metrics, REST serialization issues.
Test‑time: ensure all unit and integration tests pass under JUnit 5.
References
Spring Boot 3.0 Migration Guide: https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/
Spring Framework 6 Upgrade Guide: https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x
Hibernate 6 Release Notes: https://hibernate.org/orm/releases/6.0/
Spring Security 6 Migration Guide: https://spring.io/blog/2022/11/10/spring-security-6-0-migration-guide
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ray's Galactic Tech
Practice together, never alone. We cover programming languages, development tools, learning methods, and pitfall notes. We simplify complex topics, guiding you from beginner to advanced. Weekly practical content—let's grow together!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
