Spring Boot 2.x のプロジェクトを 3.x に上げようとしたら、コンパイルエラーが大量に出て途方に暮れた経験はありませんか。

Spring Boot 2.7.x の OSS サポートは 2023 年末で終了しており、セキュリティパッチも止まっています。移行は避けられないのですが、3.x では破壊的変更が多く、手順を知らないと作業がすぐ止まってしまいます。

この記事では javax→jakarta 置換SecurityFilterChain への移行spring.factories 廃止 という 3 つの主要な変更点に絞って対処法を整理します。末尾のチェックリストをそのまま作業シートとして使ってください。

Spring Boot 3.x で何が変わったか

主な破壊的変更は次の 3 点です。

  • javax→jakarta パッケージ名変更(Java EE から Jakarta EE 9 への移管)
  • WebSecurityConfigurerAdapter 廃止(SecurityFilterChain への強制移行)
  • spring.factories 廃止(AutoConfiguration 登録方式の変更)

それに加えて、Spring Boot 3.x は Java 17 以上 が必須です。Java 8・11 のままでは起動すらできません。

一括移行か段階的移行かはテストカバレッジとプロジェクト規模で判断しましょう。テストが薄い大規模プロジェクトであれば、フィーチャーブランチで移行を進めながら main への取り込みを段階的に行う方が安全です。

移行前の準備

javax jakarta 移行とは(用語整理)

「javax jakarta 移行」とは、Java EE から Jakarta EE 9 への移管に伴い、パッケージ名のプレフィックスが javax.* から jakarta.* に変更されたことを受けて、ソースコード内のインポート文を一括で置換する作業を指します。Spring Boot 3.x は Jakarta EE 9 をベースに採用しているため、2.x からアップグレードする際に避けて通れない作業です。

ポイントは次の 3 つです。

  • 対象は Jakarta EE 仕様に含まれるパッケージのみ(Servlet / Persistence / Validation / Annotation など)
  • JDK 標準の javax.*javax.sql / javax.crypto / javax.net)は置換不要
  • アプリ本体だけでなく、サードパーティライブラリも Jakarta 対応版へバージョンアップが必要

具体的な置換手順とコマンドは次節で解説します。

まず build.gradle の Spring Boot バージョンと Java バージョンを変更します。

plugins {
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'java'
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

変更後に ./gradlew dependencies を実行して、互換性のないサードパーティライブラリがないか確認しましょう。古いバージョンの mapstructquerydslspringfox などは Jakarta EE 非対応のものが多いので要注意です。

javax → jakarta パッケージ名変更

Spring Boot 3.x は Jakarta EE 9 ベースなので、javax.* のインポートを jakarta.* に置換する必要があります。主な対象はこちらです。

  • javax.servlet.*jakarta.servlet.*
  • javax.persistence.*jakarta.persistence.*
  • javax.validation.*jakarta.validation.*
  • javax.annotation.*jakarta.annotation.*

注意点としてjavax.sql.*javax.crypto.*javax.net.* は Jakarta EE の対象外なので置換不要です。誤って置換するとコンパイルエラーになります。

コマンドラインで一括置換する場合

find src -name "*.java" | xargs sed -i \
  -e 's/javax\.servlet/jakarta.servlet/g' \
  -e 's/javax\.persistence/jakarta.persistence/g' \
  -e 's/javax\.validation/jakarta.validation/g' \
  -e 's/javax\.annotation/jakarta.annotation/g'

IntelliJ IDEA を使っている場合は「Edit > Find > Replace in Files」で正規表現 javax\.(servlet|persistence|validation|annotation)jakarta.$1 に置換する方が手軽です。置換後は必ずビルドを走らせて残漏れがないか確認してください。

SecurityFilterChain への移行

Spring Security 6.x では WebSecurityConfigurerAdapter が完全に削除されました。2.x のコードをそのままビルドするとコンパイルエラーになります。

Before(2.x)

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}

After(3.x)

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults());
        return http.build();
    }
}

変更点をまとめると次の通りです。

  • extends WebSecurityConfigurerAdapter を削除して @Bean メソッドに変更
  • authorizeRequests()authorizeHttpRequests()
  • antMatchers()requestMatchers()
  • ラムダ DSL が標準になり .and() チェーンは不要

UserDetailsServicePasswordEncoder は以前と同じく @Bean で定義すれば OK です。Basic 認証の実装パターンは Spring Boot Security Basic認証の実装、JWT 認証は JWT認証の実装 を参照してください。

spring.factories 廃止

独自の AutoConfiguration や starter を作っていた場合、登録方式が変わっています。

Before(spring.factories)

# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.example.MyAutoConfiguration

After(.imports ファイル)

# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.MyAutoConfiguration

新しいファイルパスは META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports で、クラス名を 1 行ずつ列挙するだけです。AutoConfiguration の仕組みの詳細は Spring Boot AutoConfiguration の仕組み で解説しています。

Java 17 対応の確認ポイント

周辺ライブラリの移行ポイント

3 つの主要破壊的変更に加えて、Spring Boot 3.x では周辺ライブラリにも互換性の影響があります。実プロジェクトで詰まりやすいポイントを整理しました。

Hibernate 6 への移行

Spring Boot 3.x は Hibernate 6 系に更新されています。SQL の生成方式や型推論が変わっており、@Type アノテーションの指定方法や、hibernate.dialect の自動検出の挙動が以前と異なります。カスタム UserType を使っている場合は API 変更の影響を受けるため、Hibernate 6 のリリースノートを併読してください。論理削除を @SQLDelete / @SQLRestriction で実装している場合の注意点は Spring Boot + JPA で論理削除を実装する方法 にまとめています。

Spring Cloud Sleuth 廃止 → Micrometer Tracing

分散トレーシングのライブラリは Spring Cloud Sleuth から Micrometer Tracing へ完全に置き換わりました。spring-cloud-starter-sleuth の依存はそのままでは動かないため、micrometer-tracing-bridge-brave などのブリッジへ差し替える必要があります。具体的な設定手順は Spring Boot 3.2+ で Micrometer Tracing と Zipkin を使って分散トレーシングを導入する を参照してください。

Jackson 2.14 系の挙動差

Jackson も 2.14 系に更新され、@JsonFormat の locale 解釈や BigDecimal のシリアライズ既定値がわずかに変わっています。レスポンス JSON の差分が出る可能性があるため、契約テスト・スナップショットテストがある場合は移行直後に再生成してください。

Native Image を視野に入れるか

Spring Boot 3.0 から GraalVM Native Image が正式サポートされ、コールドスタートの大幅短縮が可能になりました。3.x への移行ついでに Native Image 化も検討する場合は Spring Boot 3.x で GraalVM Native Image を使ってネイティブコンパイルする方法 を参考にしてください。Reflection ヒントの整備など追加作業が発生するため、まずは JVM 動作で 3.x 化を完了させてから段階的に進めるのが安全です。

Java 17 ではモジュールシステムによるカプセル化が強化されており、リフレクションで内部クラスにアクセスしていたライブラリが動かないことがあります。Spring Boot 3.x 対応の依存バージョンであれば --add-opens はほぼ不要になっているので、古い JVM オプションが残っている場合は削除して動作確認しましょう。sun.* パッケージを直接使っている箇所はコンパイルエラーになるので、標準 API への置き換えが必要です。

移行後の動作確認

移行が完了したら次の順序で確認します。

  1. ./gradlew build でコンパイル・テスト通過を確認
  2. アプリを起動して actuator/healthUP を返すか確認
  3. 主要エンドポイントにスモークテストを実施
  4. MockMvc を使ったテストで Security 設定まわりを見直す

@SpringBootTest@WebMvcTest は基本的にそのまま動作しますが、Security の設定変更に合わせてテストの認証設定も確認してください。

移行チェックリスト

事前準備

  • Java 17 以上への移行確認
  • build.gradle の Spring Boot バージョンを 3.x に変更
  • ./gradlew dependencies で依存ライブラリの互換性を確認

javax→jakarta 置換

  • javax.servletjavax.persistencejavax.validationjavax.annotation を置換
  • javax.sqljavax.crypto は置換していないか確認(置換不要)
  • ビルド成功を確認

Spring Security 移行

  • WebSecurityConfigurerAdapter の継承をすべて SecurityFilterChain @Bean に変更
  • authorizeRequests()authorizeHttpRequests()antMatchers()requestMatchers() に変更

spring.factories 廃止対応

  • META-INF/spring.factoriesEnableAutoConfiguration エントリを .imports ファイルに移行

動作確認

  • ビルド成功・テスト通過
  • アプリ起動・actuator/healthUP

まとめ

Spring Boot 3.x への移行は量が多く見えますが、javax→jakarta・SecurityFilterChain・spring.factories の 3 点を押さえれば大半のエラーは解消できます。移行ブランチを切って一項目ずつ片付けていくと、思ったより早く終わりますよ。

環境ごとの設定管理には Spring Boot Profiles の活用 も参考にしてみてください。