home / skills / benchflow-ai / skillsbench / spring-boot-migration
/tasks/spring-boot-jakarta-migration/environment/skills/spring-boot-migration
This skill guides migrating Spring Boot 2.x to 3.x, updating Java versions, removing JAXB, and applying automated OpenRewrite migrations.
npx playbooks add skill benchflow-ai/skillsbench --skill spring-boot-migrationReview the files below or copy the command above to add this skill to your agents.
---
name: spring-boot-migration
description: Migrate Spring Boot 2.x applications to Spring Boot 3.x. Use when updating pom.xml versions, removing deprecated JAXB dependencies, upgrading Java to 17/21, or using OpenRewrite for automated migration. Covers dependency updates, version changes, and migration checklist.
---
# Spring Boot 2 to 3 Migration Skill
## Overview
This skill provides guidance for migrating Spring Boot applications from version 2.x to 3.x, which is one of the most significant upgrades in Spring Boot history due to the Java EE to Jakarta EE transition.
## Key Migration Steps
### 1. Update Spring Boot Version
Change the parent POM version:
```xml
<!-- Before: Spring Boot 2.7.x -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<!-- After: Spring Boot 3.2.x -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
```
### 2. Update Java Version
Spring Boot 3 requires Java 17 or later:
```xml
<properties>
<!-- Before -->
<java.version>1.8</java.version>
<!-- After -->
<java.version>21</java.version>
</properties>
```
### 3. Remove Deprecated Dependencies (CRITICAL: JAXB API)
**You MUST remove the old `javax.xml.bind:jaxb-api` dependency.** This is a Java EE dependency that was commonly added for Java 9+ compatibility in Spring Boot 2.x projects, but it conflicts with Jakarta EE in Spring Boot 3.
#### Dependencies to REMOVE from pom.xml
```xml
<!-- REMOVE ALL OF THESE - they are incompatible with Spring Boot 3 -->
<!-- Old JAXB API - MUST BE REMOVED -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<!-- Old JAXB Implementation - MUST BE REMOVED -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
</dependency>
<!-- Old Java Activation - MUST BE REMOVED -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
</dependency>
```
#### Why Remove These?
1. **Namespace Conflict**: `javax.xml.bind` uses the old Java EE namespace, which conflicts with Jakarta EE's `jakarta.xml.bind`
2. **Spring Boot 3 Includes Jakarta XML Bind**: If you need XML binding, Spring Boot 3 transitively includes the Jakarta versions
3. **Build Failures**: Having both `javax.xml.bind` and `jakarta.xml.bind` on the classpath causes ClassNotFoundException and other runtime errors
#### If You Need XML Binding in Spring Boot 3
Use the Jakarta versions instead:
```xml
<!-- Only add these if you actually need XML binding -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
```
#### Quick Check for Old JAXB Dependencies
```bash
# Check if old JAXB is in your pom.xml
grep -E "javax\.xml\.bind|jaxb-api" pom.xml
# If this returns any results, you need to remove those dependencies
```
#### Verify Removal
After removing, confirm no old JAXB references remain:
```bash
# This should return NO results
grep -E "<artifactId>jaxb-api</artifactId>" pom.xml
grep -E "javax\.xml\.bind" pom.xml
```
### 4. Update JWT Library
The old `jjwt` library needs to be replaced with the newer modular version:
```xml
<!-- Before -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- After -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
```
## Common Issues
### Issue 1: Compilation Errors After Upgrade
After changing the Spring Boot version, you'll see many compilation errors related to `javax.*` imports. These need to be changed to `jakarta.*` (see Jakarta Namespace skill).
### Issue 2: H2 Database Dialect
The H2 dialect class name changed:
```properties
# Before
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# After
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Note: In Hibernate 6, this is often auto-detected and may not need explicit configuration
```
### Issue 3: Actuator Endpoints
Actuator endpoint paths have changed. Review your security configuration if you're exposing actuator endpoints.
## Migration Commands
### Update pom.xml with sed
```bash
# Update Spring Boot parent version
sed -i 's/<version>2\.7\.[0-9]*<\/version>/<version>3.2.0<\/version>/g' pom.xml
# Update Java version
sed -i 's/<java.version>1\.8<\/java.version>/<java.version>21<\/java.version>/g' pom.xml
sed -i 's/<java.version>8<\/java.version>/<java.version>21<\/java.version>/g' pom.xml
sed -i 's/<java.version>11<\/java.version>/<java.version>21<\/java.version>/g' pom.xml
# Remove old JAXB dependency (multi-line removal is complex - manual removal recommended)
```
### Remove Deprecated Dependencies
```bash
# Check for old JAXB dependencies
grep -n "jaxb-api\|javax\.xml\.bind" pom.xml
# These must be manually removed from pom.xml:
# - javax.xml.bind:jaxb-api
# - com.sun.xml.bind:jaxb-impl
# - com.sun.xml.bind:jaxb-core
```
## Using OpenRewrite for Automated Migration
OpenRewrite is the recommended tool for large-scale migrations:
### Add OpenRewrite Plugin to pom.xml
```xml
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.42.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>5.21.0</version>
</dependency>
</dependencies>
</plugin>
```
### Run OpenRewrite Migration
```bash
mvn rewrite:run
```
This will automatically:
- Update Spring Boot version
- Migrate `javax.*` to `jakarta.*` imports
- Update deprecated Spring Security patterns
- Fix property name changes
## Verification Steps
### Check Spring Boot Version
```bash
# Should show 3.x version
grep -A2 "spring-boot-starter-parent" pom.xml | grep version
```
### Check Java Version
```bash
# Should show 17 or 21
grep "java.version" pom.xml
```
### Check for Old Dependencies
```bash
# All should return NO results
grep "jaxb-api" pom.xml
grep "javax\.xml\.bind" pom.xml
grep "<version>0\.9\.1</version>" pom.xml # Old jjwt version
```
### Compile and Test
```bash
# Compile the project
mvn clean compile
# Run tests
mvn test
```
## Migration Checklist
- [ ] Update `spring-boot-starter-parent` version to 3.2.x
- [ ] Update `java.version` to 17 or 21
- [ ] Remove `javax.xml.bind:jaxb-api` and related JAXB dependencies
- [ ] Remove old `io.jsonwebtoken:jjwt` if present, replace with modular jjwt
- [ ] Run `mvn clean compile` to identify remaining issues
- [ ] Fix all `javax.*` to `jakarta.*` imports
- [ ] Update Spring Security configuration (see Spring Security 6 skill)
- [ ] Replace RestTemplate with RestClient (see RestClient Migration skill)
- [ ] Run tests to verify functionality
## Recommended Migration Order
1. **First**: Upgrade to Spring Boot 2.7.x (latest 2.x) if not already
2. **Second**: Update Java version to 17 or 21
3. **Third**: Remove incompatible dependencies (JAXB, old JWT)
4. **Fourth**: Update Spring Boot parent to 3.2.x
5. **Fifth**: Fix namespace imports (javax → jakarta)
6. **Sixth**: Update Spring Security configuration
7. **Seventh**: Update HTTP clients (RestTemplate → RestClient)
8. **Finally**: Run full test suite
## Sources
- [Spring Boot 3.0 Migration Guide](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide)
- [OpenRewrite Spring Boot 3 Migration](https://docs.openrewrite.org/running-recipes/popular-recipe-guides/migrate-to-spring-3)
- [Baeldung - Migrate to Spring Boot 3](https://www.baeldung.com/spring-boot-3-migration)
This skill guides migrating Spring Boot 2.x applications to Spring Boot 3.x, focusing on the Jakarta EE namespace change, Java version upgrade, and dependency updates. It provides a practical checklist, commands, and automated options (OpenRewrite) to streamline large or small codebases.
The skill inspects pom.xml for Spring Boot parent version, java.version, and problematic dependencies such as old JAXB and legacy jjwt. It outlines the manual edits and sed commands to update versions, shows which dependencies must be removed or replaced, and describes running OpenRewrite to apply automated code transformations (javax -> jakarta, security updates, property fixes). It concludes with verification and test steps to validate the migration.
Do I always need to remove javax.xml.bind dependencies?
Yes—old javax.xml.bind artifacts conflict with Jakarta EE in Spring Boot 3 and must be removed; add jakarta.xml.bind only if you need XML binding.
Can I skip OpenRewrite and do changes manually?
You can, but OpenRewrite saves time on large codebases by reliably converting imports, properties, and common patterns; manual edits are feasible for small projects.
What Java versions are supported for Spring Boot 3?
Spring Boot 3 requires Java 17 or later; using Java 21 is recommended for new projects.