Contents
1. 移行前の事前評価と準備
1‑1 Java バージョン要件
Spring Boot 3.x は 最低 Java 17(LTS)を必須とします。プロジェクト全体で java.version、sourceCompatibility、targetCompatibility が 17 以上に設定されているか確認してください。
| 設定ファイル | 確認項目 |
|---|---|
pom.xml |
<java.version>17</java.version> が存在するか |
build.gradle |
sourceCompatibility = JavaVersion.VERSION_17 が設定されているか |
1‑2 Jakarta EE 名前空間への移行
Spring Boot 3.x は Jakarta EE 9+ に対応し、すべての javax.* パッケージが jakarta.* に置き換わります。代表的な変更点は次の通りです。
| 旧パッケージ | 新パッケージ |
|---|---|
javax.servlet.* |
jakarta.servlet.* |
javax.validation.* |
jakarta.validation.* |
javax.persistence.* |
jakarta.persistence.* |
影響範囲の把握手順
- IDE の全プロジェクト検索で
javax.をキーワードに検索 - 検索結果を一覧化し、
jakarta.へのリファクタリング対象としてマーク
公式ガイド: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#migration
1‑3 依存関係・サードパーティライブラリの互換性チェック
Maven の場合
|
1 2 3 |
./mvnw dependency:tree -Dincludes=org.springframework | grep spring-boot ./mvnw versions:display-dependency-updates |
Gradle の場合
|
1 2 3 |
./gradlew dependencies --configuration runtimeClasspath | grep spring-boot ./gradlew dependencyUpdates -Drevision=release |
チェックポイント
| 項目 | 確認すべき点 |
|---|---|
| Spring Framework バージョン | 6.x 系列が使用できているか |
| Spring Data / Security 等 | それぞれ 3.x 対応版がリリースされているか |
| 非公式サードパーティ (例: MyBatis, Thymeleaf) | Jakarta EE に対応した最新バージョンを使用しているか |
1‑4 ビルドツール設定の現状把握
| 設定項目 | 主な確認ポイント |
|---|---|
spring-boot-starter-parent(Maven) |
バージョンが 2.x 系になっていないか |
| Spring Boot Gradle Plugin | id 'org.springframework.boot' version '3.x.x' に更新できるか |
| Starter 名 | 大半は変更なし。ただし validation と websocket の一部 starter が Jakarta 対応版に置き換わっている点に注意 |
2. ビルドツールとコードベースの更新
2‑1 Java バージョン設定例
Maven (pom.xml)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<properties> <java.version>17</java.version> <spring-boot.version>3.2.4</spring-boot.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot.version}</version> <relativePath/> <!-- lookup parent from repository --> </parent> |
Gradle (build.gradle)
|
1 2 3 4 5 6 7 8 9 10 11 |
plugins { id 'org.springframework.boot' version '3.2.4' id 'io.spring.dependency-management' version '1.1.5' id 'java' } java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } |
ポイント:
spring-boot-starter-parentのバージョンを明示的に管理することで、依存の統一が保証されます(公式推奨)。
2‑2 Spring Boot プラグインと Gradle Wrapper のアップデート
| ツール | 更新手順 |
|---|---|
| Maven | spring-boot.version を最新 3.x 系に変更し、./mvnw clean verify でビルドが通るか確認 |
| Gradle | plugins { id 'org.springframework.boot' version '3.2.4' } に書き換えた後、./gradlew wrapper --gradle-version=8.5 で Wrapper を最新にする |
2‑3 IDE 支援によるパッケージ名一括置換
IntelliJ IDEA(例)
- Refactor → Migrate Packages を選択
javax.→jakarta.のマッピングテーブルを作成(テンプレートが用意されている)- 変更後は必ず Reimport Maven/Gradle Projects を実行し、ビルドエラーが出ないか検証
VS Code / Eclipse
- 「Search & Replace」機能で
javax.→jakarta.に置換し、Ctrl+Shift+Pから Java: Clean Workspace を実行
注意: サードパーティ JAR が直接参照している
javax.*クラスは、該当ライブラリの Jakarta 対応版へアップデートする必要があります。
2‑4 まとめ(ポイント)
- Maven/Gradle の
java.versionと Spring Boot プラグインを 3.x 系 + Java 17 に統一 - IDE のパッケージリファクタリングで
javax.*→jakarta.*を自動置換 - 変更後は必ず依存解決とビルドの クリーンビルド(
./mvnw clean verify/./gradlew clean build)を走らせ、エラーが無いことを確認
3. Spring ライブラリ・API の適応
3‑1 主要ライブラリ別 API 変更ポイント
| ライブラリ | 2.x での代表的構成 | 3.x への移行ポイント |
|---|---|---|
| Spring Security | WebSecurityConfigurerAdapter を継承 |
SecurityFilterChain Bean 定義へ置換(公式ブログ: https://spring.io/blog/2022/05/24/spring-security-without-websecurityconfigureradapter) |
| Spring Data JPA | javax.persistence.* を使用 |
すべて jakarta.persistence.* に変更。エンティティクラスのインポートだけでなく、persistence.xml(利用している場合)も更新 |
| Spring Test | spring.factories に自動構成を記述 |
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports へ移行(公式リファレンス: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing) |
| Spring Validation | spring-boot-starter-validation が javax.validation を使用 |
バージョン 3.x 系は自動的に jakarta.validation に切り替わるので、インポートの変更だけで OK |
3‑1‑a Security 設定例(移行前後)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 2.x (廃止予定) @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and().formLogin(); } } // 3.x (推奨) @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); } } |
3‑2 Starter 名の変更と自動構成ファイル
- ほとんどの starter は名称が変わっていません。例外的に
spring-boot-starter-validationが内部で Jakarta Validation に切り替わりますが、名前は同一です。 -
spring.factoriesの廃止に伴う自動構成ファイル移行手順 -
既存の
src/main/resources/META-INF/spring.factoriesを削除 - 同じディレクトリ配下に
org.springframework.boot.autoconfigure.AutoConfiguration.importsという名前でテキストファイルを作成 - 旧ファイルに列挙されていた全クラス名(1行につき1エントリ)を書き込む
|
1 2 3 4 |
# src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports com.example.MyAutoConfiguration org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration |
3‑3 まとめ(ポイント)
- Security は
WebSecurityConfigurerAdapterを廃止し、SecurityFilterChainBean に置き換えるだけでほぼ完了 - JPA・Validation のインポートは 全て jakarta パッケージへ 書き換え
spring.factories→AutoConfiguration.importsへの移行はファイル名と配置場所を正しく保つことが唯一の要件
4. テスト・デプロイ環境での検証
4‑1 テストフレームワークのアップデート
| 変更項目 | 旧コード例 | 新コード例 |
|---|---|---|
| JUnit ランナー | @RunWith(SpringRunner.class) |
@ExtendWith(SpringExtension.class)(JUnit 5 がデフォルト) |
| Spring Boot Test アノテーション | 変わらず (@SpringBootTest) |
同上だが webEnvironment = RANDOM_PORT 推奨 |
| Mockito/JUnit の互換性 | org.mockito.junit.MockitoJUnitRunner |
@ExtendWith(MockitoExtension.class) |
4‑1‑a 統合テスト例(Testcontainers 使用)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class UserRepositoryIntegrationTest { @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15-alpine") .withDatabaseName("testdb") .withUsername("user") .withPassword("pass"); @Autowired private UserRepository repository; @Test void whenFindById_thenReturnUser() { // テストロジック(例:保存 → 取得) } } |
4‑2 Dockerfile の Java 17 対応
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# ------------------------------------------------- # Stage 1 – Build (optional if you use a CI build) # ------------------------------------------------- FROM eclipse-temurin:17-jdk-alpine AS builder WORKDIR /workspace COPY . . RUN ./mvnw -B package -DskipTests # ------------------------------------------------- # Stage 2 – Runtime # ------------------------------------------------- FROM eclipse-temurin:17-jre-alpine VOLUME /tmp ARG JAR_FILE=target/*.jar COPY --from=builder /workspace/${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] |
4‑3 CI/CD パイプラインの Java 17 設定例
GitHub Actions(公式サンプル)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
name: CI on: push: branches: [ main ] pull_request: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: temurin java-version: '17' - name: Build with Maven run: ./mvnw -B verify |
Jenkins(公式プラグイン利用)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
pipeline { agent any tools { jdk 'jdk-17' } stages { stage('Build') { steps { sh './mvnw clean package -DskipTests' } } stage('Test') { steps { sh './mvnw verify' } } } } |
公式リファレンス:
- GitHub Actions JDK 設定 https://docs.github.com/en/actions/using-jobs/setting-up-a-job-environment#specifying-the-java-version
- Jenkins JDK ツール設定 https://www.jenkins.io/doc/book/tools/#jdk
4‑4 まとめ(ポイント)
- テストは JUnit 5 + SpringBootTest に統一し、外部リソースは Testcontainers で実装
- Dockerfile は
eclipse-temurin:17系イメージへ切り替えるだけでビルド・ランタイムが完結 - CI/CD ツールは公式プラグインを用いて JDK 17 を明示的に指定し、ビルドフェーズの失敗を防止
5. 移行後のパフォーマンス測定とトラブルシューティング
5‑1 ベンチマーク指標と取得手順
| 指標 | 測定方法 |
|---|---|
| 起動時間 | Spring Boot Actuator の startup.time メトリクス (/actuator/metrics/startup.time) を有効化し、数回の平均を取る |
| ヒープ使用量 | JVM 起動オプション -XX:+PrintGCDetails -Xlog:gc*: で GC ログ取得後、jcmd VM.native_memory summary で確認 |
| スループット / レイテンシ | JMH (Java Microbenchmark Harness) を使用し、主要エンドポイントのベンチマークを実装 |
JMH サンプル(起動時間測定)
|
1 2 3 4 5 6 7 8 9 10 |
@BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) public class StartupBenchmark { @Benchmark public void springBoot3Startup() { SpringApplication.run(MyApp.class); } } |
公式 JMH ガイド: https://openjdk.org/projects/code-tools/jmh/
5‑2 典型的な起動・コンパイルエラーと対処法
| エラーメッセージ | 主因 | 解決策 |
|---|---|---|
ClassNotFoundException: jakarta.servlet.Filter |
javax.servlet.* が残存、または spring-boot-starter-web のバージョンが 2.x |
全ての javax.servlet インポートを置換し、Starter を 3.2.x に更新 |
NoSuchMethodError: org.springframework.boot.SpringApplication.run |
Spring Boot ライブラリが混在(2.x と 3.x が同時にクラスパス上) | dependencyManagement で spring-boot-dependencies:3.2.4 を統一し、古いバージョンの依存を除外 |
Failed to configure a DataSource |
JDBC ドライバが Jakarta EE 未対応(例:古い PostgreSQL driver) | postgresql:42.7.1 以上にアップデート(Jakarta 対応版) |
AutoConfiguration.imports not found |
spring.factories が残っている、またはファイルパスが誤り |
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports を正しい場所に配置し、内容を確認 |
5‑3 長期的なメンテナンスプラン
| サイクル | 実施項目 |
|---|---|
| 毎月 | ./mvnw versions:display-dependency-updates(または Gradle の dependencyUpdates) で利用ライブラリの新バージョンを把握 |
| 四半期 | Spring Boot マイナーバージョン(例:3.2 → 3.3)への自動アップデートパイプラインを構築。テストスイートがすべて成功することを必須条件に |
| 年次 | Java LTS のリリースサイクルを踏まえ、Java 21 が GA した場合の移行計画を策定(ただし現時点では Java 17 が推奨) |
総括:Spring Boot 2 → 3 移行チェックリスト
| フェーズ | 主な作業項目 |
|---|---|
| 事前評価 | Java 17 必須化、Jakarta EE 名前空間変更の影響範囲洗い出し、依存バージョン互換性確認 |
| ビルド設定更新 | java.version/sourceCompatibility → 17、Spring Boot Plugin を 3.x 系へ、IDE のパッケージリファクタリング実施 |
| API 適応 | Security, Data JPA, Validation 等のコードを Jakarta パッケージに置換し、spring.factories → AutoConfiguration.imports に移行 |
| テスト・デプロイ | JUnit 5 + Testcontainers でテスト網羅、Dockerfile と CI/CD の Java 17 設定更新 |
| パフォーマンス測定 | Actuator メトリクスと JMH で起動時間・メモリをベンチマーク、典型的エラーの対策を実装 |
| 保守計画 | 月次依存アップデート、四半期マイナーバージョン自動化、年次 Java LTS 移行検討 |
公式移行ガイド(英日版)
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#migration
このチェックリストに沿って段階的に作業を進めれば、安全かつスムーズに Spring Boot 3.x へ移行 でき、同時に Java 17 の長期サポート恩恵も享受できます。ぜひプロジェクトの実情に合わせてカスタマイズし、継続的なアップデート体制を構築してください。