Step-by-Step Guide to Migrating Spring Boot 2.x to 3.x (2024)
This practical guide walks you through every stage of upgrading a Spring Boot 2.x application to 3.x, covering pre‑migration preparation, dependency changes, code refactoring, security configuration updates, configuration file adjustments, third‑party library compatibility, common pitfalls, verification steps, and optional native image building.
Pre‑Migration Checklist
Backup the project : Use Git, keep a clean working tree, and create a new branch for the upgrade.
Check current version : Identify the exact Spring Boot 2.x version (e.g., 2.7.18), upgrade to the latest patch of that branch before jumping to 3.x.
Read the official migration guides :
Spring Boot 3.0 Migration Guide
Spring Framework 6.0 Migration Guide
Upgrade Java : Spring Boot 3.x requires Java 17 or newer (21 LTS recommended). Align your development, CI/CD, and server environments.
Third‑party dependency check :
Run ./mvnw dependency:tree or gradle dependencies to view the dependency graph.
Verify that libraries such as MyBatis, Redis, Kafka, SpringDoc have Boot 3 compatible versions.
Replace the MySQL driver with mysql-connector-j (the old mysql-connector-java is deprecated).
Automated migration tool (recommended) : Add OpenRewrite to the build to automatically convert javax.* to jakarta.* and rename properties.
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.29.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5</recipe>
</activeRecipes>
</configuration>
</plugin>Execute with ./mvnw -U rewrite:run.
Core Changes and Practical Modification Steps
1. Update pom.xml / build.gradle
Maven example:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.5</version> <!-- current stable version -->
</parent>
<properties>
<java.version>17</java.version>
</properties>2. Code migration: javax.* → jakarta.*
Key namespace changes:
Servlet: javax.servlet.* → jakarta.servlet.* JPA: javax.persistence.* → jakarta.persistence.* Validation: javax.validation.* → jakarta.validation.* Annotations: javax.annotation.* → jakarta.annotation.* Example:
// Boot 2.x
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
// Boot 3.x
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotNull;3. Spring Security 6 configuration changes
Old (Boot 2.x) – extends WebSecurityConfigurerAdapter:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated();
}
}New (Boot 3.x) – define a SecurityFilterChain bean:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated())
.formLogin(Customizer.withDefaults())
.build();
}
}4. Configuration file changes
server.max-http-header-size→ server.max-http-request-header-size Spring MVC now uses PathPatternParser instead of AntPathMatcher for path matching.
Spring Sleuth is deprecated; switch to Micrometer Tracing (with OpenTelemetry/Zipkin).
Validate differences with:
./mvnw spring-boot:validate -Dspring-boot.version=3.5.5Third‑Party Library Adaptation
SpringDoc OpenAPI → upgrade to springdoc-openapi-starter-webmvc-ui:2.8.x.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.11</version>
</dependency>MySQL driver → use mysql-connector-j.
Lombok → upgrade to 1.18.24+.
Test dependencies → switch to spring-boot-starter-test compatible with Boot 3.x.
Common Issues & Solutions (Q&A)
ClassNotFoundException / NoSuchMethodError
Cause: dependency conflicts or old libraries.
Fix: run mvn dependency:tree and exclude outdated versions.
Missing javax classes
Cause: outdated Hibernate or Validator versions.
Fix: rely on Spring Boot managed versions and remove manual old dependencies.
Spring Security errors
Cause: WebSecurityConfigurerAdapter removed.
Fix: replace with a SecurityFilterChain bean as shown above.
Configuration properties not taking effect
Cause: property renamed or deprecated.
Fix: consult the official migration guide or run spring-boot:validate.
Tracing disabled
Cause: Spring Sleuth removed.
Fix: switch to Micrometer Tracing + OpenTelemetry/Zipkin .
Post‑Upgrade Validation
Compile successfully – ensure no javax.* references remain.
API test – hit /actuator/health endpoint.
Security verification – test login and authorization flows.
Database operations – confirm JPA/MyBatis work as expected.
Monitoring & logging – verify Micrometer metrics and tracing are functional.
Bonus: AOT & Native Image
Spring Boot 3.x supports GraalVM Native Image for faster startup and lower memory usage.
Build command: ./mvnw -Pnative spring-boot:build-image Ideal for sidecar services, serverless functions, and microservice gateways.
Conclusion
The essential tasks for upgrading from Spring Boot 2.x to 3.x are:
Environment: use JDK ≥ 17.
Jakarta namespace: replace all javax imports with jakarta.
Dependency alignment: manage third‑party libraries via the BOM and replace deprecated ones (e.g., MySQL driver).
Configuration updates: watch for renamed properties, PathPattern changes, and tracing migration.
Security rewrite: replace WebSecurityConfigurerAdapter with SecurityFilterChain.
It is recommended to perform the upgrade on an isolated branch, leverage OpenRewrite for automated refactoring, and validate the result with regression tests and monitoring checks to ensure a smooth transition.
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.
