Migrating from Spring Boot 2.x to 3.x isn't just a version bump — it's a move to Jakarta EE, Java 17+, and a new baseline. Here's everything that actually matters, distilled from migrating three production services.
The Big Breaking Change: javax → jakarta
Every import starting with javax.* needs to change to jakarta.*. This sounds simple but touches everything: servlets, persistence, validation, mail. Use your IDE's find-and-replace, but manually verify edge cases.
Java 17 Baseline
Spring Boot 3 requires Java 17 minimum. If you're still on 11, this is the bigger migration. The good news: records, sealed classes, and pattern matching make your code significantly cleaner.
Spring Security Overhaul
The SecurityFilterChain approach is now the only way. WebSecurityConfigurerAdapter is gone. If you haven't already migrated your security config, this is the most labor-intensive change. I've included before/after examples for common patterns: JWT auth, OAuth2, and method-level security.
Observability Changes
Micrometer is now the default observation API. Spring Boot Actuator endpoints have changed paths. If you have monitoring dashboards, update them before deploying.
My Migration Checklist
1. Upgrade to the latest Spring Boot 2.7.x first
2. Fix all deprecation warnings
3. Switch to Java 17
4. Run the OpenRewrite migration recipe
5. Manually fix what OpenRewrite misses
6. Update security configuration
7. Test everything — especially integration tests
8. Update monitoring and alerting
The whole process took about 2 days per service for us, with most time spent on security configuration and integration test fixes.