Java

javaxからjakartaへの移行手順:Tomcat 10以降とSpring Boot 3で書き換える箇所と検出コマンド

javaxからjakartaへの移行手順:Tomcat 10以降とSpring Boot 3で書き換える箇所と検出コマンド

Tomcat 10.1や11.0、Spring Boot 3以降へ上げると、javax.servletやjavax.persistenceで書いたコードはそのままでは動きません。ただし、書き換えるのはJava EE由来のAPIだけで、javax.sqlのようにJDKに含まれるパッケージはjavaxのまま残します。この記事では、名前が変わる範囲の見分け方、残っているjavaxをgrepと依存ツリーで洗い出す方法、Maven座標の差し替えとOpenRewriteによる一括書き換え、persistence.xmlなど設定ファイルの差分までを、2026年11月3日時点の公式ドキュメントとMaven Centralの版番号に沿って整理します。

まとめ|依存の差し替えから始め、残ったjavaxを機械的に検出して潰す

javaxからjakartaへの移行は、文字列の一括置換では終わりません。正しい順序は「依存ライブラリをjakarta版の座標へ差し替える」「OpenRewriteでソースと設定を書き換える」「grepと依存ツリーで残りを検出する」の3段です。一括置換を先に行うと、javax.sql.DataSourceのようなJDKのクラスまで壊れます。

移行先がTomcat 11やSpring Boot 3以降なら、OpenRewriteのレシピはJakarta EE 9向けのJavaxMigrationToJakartaではなく、JakartaEE10かJakartaEE11を選ぶ方針です。ソースを直せない部品が残るときだけ、Tomcatの移行ツールでWARごと変換します。jakarta対応版が無い部品が業務の中心にあるなら、移行を急がず9.1系で期限を延ばす判断もあります。

javaxからjakartaへ名前が変わる範囲とJDKに残るjavaxパッケージの見分け方

Jakarta EE 9で変わったのはJava EE由来のAPI名で仕様の中身はほぼ同じ

パッケージ名が変わったのはJakarta EE 9からです。Jakarta EE Platform 9の仕様ページによると、仕様委員会のリリース投票は2020年11月20日に完了しました。OpenRewriteのJakarta EE 9移行レシピの定義でも、EE 9を「新しいjakarta名前空間を使う最初の版」と説明しています。

EE 9はAPIの中身をほぼ変えず、名前だけを移した版です。HttpServletRequestのメソッドも@Entityの使い方も同じで、変わるのはimport文とパッケージを含む文字列です。Tomcatでいえば、9.0系がJava EE 8(javax)、10.1系と11.0系がJakarta EE(jakarta)の実装にあたります。系列ごとの対応表と期限はTomcatのバージョン一覧とサポート期限にまとめています。

見落としやすい落とし穴が1つあります。jakarta.servlet:jakarta.servlet-apiの4.0.4やjakarta.persistence-apiの2.2.3は、座標こそjakartaでも中身はjavaxパッケージのままです。これらはJakarta EE 8の版で、名前空間の移行より前に作られました。座標がjakartaでも版が古ければ移行済みとはいえません。

javax.sqlやjavax.transaction.xaはJDKの一部で変更不要

JDKには、Java EEとは無関係なjavaxパッケージが今も含まれています。Java SE 17のAPI仕様では、java.sqlモジュールがjavax.sqlを、java.transaction.xaモジュールがjavax.transaction.xaをエクスポートしています。java.baseモジュールのjavax.cryptoやjavax.netも同じ扱いです。

旧パッケージ 移行後 由来
javax.servlet jakarta.servlet Java EE
javax.persistence jakarta.persistence Java EE
javax.validation jakarta.validation Java EE
javax.transaction jakarta.transaction Java EE
javax.transaction.xa 変更しない JDK
javax.sql 変更しない JDK
javax.crypto 変更しない JDK

表のjavax.transactionとjavax.transaction.xaのように、前方一致では区別できない組み合わせがあります。@Transactionalは移行しますが、XAResourceはJDKのまま残す対象です。sedでjavax.をjakarta.へ一括置換すると、この区別が消えてコンパイルが通らなくなります。

移行前にjavaxが残る箇所を洗い出すgrepとMavenの依存ツリーの確認

ソースと設定ファイルからJava EE由来のjavaxだけを拾うgrepの書き方

最初に、どこにどれだけjavaxがあるかを数えます。Java EE由来のパッケージ名を列挙して検索すれば、JDKのjavaxは拾いません。import文だけでなく、XMLやプロパティファイル、META-INF/servicesのファイル名も対象に含めます。

# Java EE 由来の javax を、ソース・設定・JSP から拾う(javax.sql や javax.crypto は対象外)
grep -rnE 'javax\.(servlet|persistence|validation|annotation\.(PostConstruct|PreDestroy|Resource)|inject|ws\.rs|xml\.bind|mail|faces|el\.|websocket|jms|ejb|enterprise|transaction\.[A-Z])' \
  --include='*.java' --include='*.xml' --include='*.properties' --include='*.jsp' --include='*.tld' src/

# ファイル名に javax を含む ServiceLoader 定義を探す
find src -path '*META-INF/services/javax.*'

transaction\.[A-Z]はクラス名の先頭が大文字であることを使い、javax.transaction.xaを除外する書き方です。件数はモジュールごとに記録しておくと、書き換え後に同じコマンドで0件を確かめられます。

mvn dependency:treeで推移的に入るjavax系の依存を見つける手順

自分のコードを直しても、依存ライブラリがjavaxのAPIを引き込んでいれば同じクラスパスに新旧が混ざります。maven-dependency-pluginのtreeゴールはincludesによる絞り込みが可能です。書式は[groupId]:[artifactId]:[type]:[version]で、各部分に*を使えます。

# groupId が javax. で始まる依存が、どのライブラリ経由で入っているかを表示する
mvn dependency:tree -Dincludes='javax.*'

# jakarta 座標でも中身が javax の Jakarta EE 8 版(例:servlet-api 4.x)を探す
mvn dependency:tree -Dincludes='jakarta.servlet:jakarta.servlet-api:jar:4.*'

ツリーの上位に出てくるライブラリが、jakarta対応版への差し替え対象です。ライブラリ側にjakarta対応版が無いと分かった時点で、そのモジュールは後述のWAR変換か延命の判断へ回します。

依存ライブラリをjakarta版の座標へ差し替えるpom.xmlの書き換え例

ServletやPersistenceのMaven座標と移行先の版の対応表

差し替え先の版は、移行先のTomcatが実装する仕様に合わせます。Tomcatの版一覧によると、11.0系(最新11.0.27)はServlet 6.1とJava 17以降、10.1系はServlet 6.0とJava 11以降です。Maven Centralの正式版(2026年11月3日時点)を並べると次のとおりです。

API 旧artifactId 新artifactId EE 10 EE 11
Servlet javax.servlet-api jakarta.servlet-api 6.0.0 6.1.0
Persistence javax.persistence-api jakarta.persistence-api 3.1.0 3.2.0
Validation validation-api jakarta.validation-api 3.0.2 3.1.1
Annotation javax.annotation-api jakarta.annotation-api 2.1.1 3.0.0

groupIdも旧座標のjavax.servletなどから、jakarta.servletのようにjakarta.で始まる名前へ変わります。Servlet APIはTomcat本体が提供するので、providedスコープでの宣言が必要です。版の一覧はMaven Centralのjakarta.servlet-apiのページで確かめられます。Hibernateのように実装側もjavaxから移った製品は、APIの座標だけでなく実装の版も上げます(Hibernate 6系からorg.hibernate.ormのgroupIdになりました)。

Maven Enforcerで旧javax系の依存の再混入を止める設定

一度きれいにしても、ライブラリの更新で旧APIが推移的に戻ってくることがあります。Maven EnforcerのbannedDependenciesルールを入れておくと、ビルドの時点で失敗させられます。推移的な依存もチェックするsearchTransitiveは既定でtrueです。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>3.7.0</version>
  <executions>
    <execution>
      <id>ban-javax-ee</id>
      <goals><goal>enforce</goal></goals>
      <configuration>
        <rules>
          <bannedDependencies>
            <excludes>
              <exclude>javax.servlet</exclude>
              <exclude>javax.persistence</exclude>
              <exclude>javax.validation</exclude>
              <exclude>javax.annotation</exclude>
              <exclude>jakarta.servlet:jakarta.servlet-api:[,5.0.0)</exclude>
            </excludes>
            <message>Java EE の javax API が混入しています。jakarta 版へ差し替えてください</message>
          </bannedDependencies>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

最後のexcludeは、jakarta座標のまま中身がjavaxの4.x系を版範囲で止める指定です。移行中のモジュールが残っている間は、移行が済んだモジュールのpom.xmlから順に入れていきます。

OpenRewriteのJakartaEE11レシピでソースと設定を一括で書き換える手順

pom.xmlを変えずにrewrite-maven-pluginを実行するコマンド

OpenRewriteは、コードの構文木を読んでから書き換えるため、JDKのjavaxを壊しません。公式ドキュメントのpom.xmlを変更しない実行方法に沿うと、レシピの配布物と有効にするレシピをコマンドラインで渡せます。

# 作業用ブランチで実行し、結果は git diff で確認する
git switch -c jakarta-migration

# Tomcat 11 / Jakarta EE 11 へ移す場合(10.1 なら JakartaEE10 を指定する)
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
  -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:RELEASE \
  -Drewrite.activeRecipes=org.openrewrite.java.migrate.jakarta.JakartaEE11

git diff --stat

レシピの選び方には注意が要ります。JavaxMigrationToJakartaはEE 9向けで、Servlet APIを5.0系へ上げる定義です。Tomcat 10.1系ならJakartaEE10(Servlet APIは6.0系)、11.0系ならJakartaEE11を指定します。JakartaEE11は内部でJakartaEE10を、JakartaEE10はJavaxMigrationToJakartaを呼び出す入れ子構造なので、EE 9を経由して2回流す必要はありません。

レシピが書き換える範囲と文字列やリフレクションで残る手作業の箇所

EE 9向けのレシピ定義には、Servlet・Persistence・Validation・Inject・Mail・XML Bindなど約30の個別レシピが並び、persistence.xmlやorm.xmlの書き換えも含まれます。EE 10向けにはbeans.xml・validation.xmlの名前空間や、Servlet 6.0で削除されたメソッドの置き換えが加わります。

残りやすいのは、構文木からは型と分からない箇所です。

  • Class.forName("javax.servlet.http.HttpServlet")のような文字列でのクラス指定
  • Spring XMLやログ設定ファイルに書いたクラス名
  • 独自に書いたアノテーションプロセッサやバイトコード操作のパッケージ指定
  • テスト用のモックライブラリが参照する旧APIの版

レシピ実行後に前章のgrepをもう一度流し、残った行を1件ずつ確認します。0件にならない行の多くは、上の4種類のどれかです。

web.xmlとpersistence.xmlのスキーマ宣言とプロパティ名の差分

web.xmlのスキーマ宣言は旧版のままでも動き書き換えは急がなくてよい

XML記述子のスキーマ宣言は、すぐに書き換えなくても動きます。Tomcat移行ツールのREADMEは、XMLスキーマの参照は移行不要で、Jakarta EE 9以降もJava EE 8以前のスキーマを引き続きサポートすると説明しています。web.xmlのversion="4.0"は、移行直後の段階ではそのまま残して構いません。

注意するのは、要素の中身に書いたクラス名です。<filter-class>や<listener-class>に自作クラスを書いている分には変わりませんが、javax.servletのクラスを直接指定している行は書き換えが必要です。

persistence.xmlのjakartaプロパティ名と3.0スキーマ宣言

Jakarta Persistenceでは、プロパティ名も変わりました。Jakarta Persistence 3.0仕様の冒頭には、名前にjavaxを含むプロパティはすべてjavaxをjakartaに置き換えた名前へ変更した、と書かれています。スキーマはpersistence_3_0.xsdで公開されています。

<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
  <persistence-unit name="app">
    <properties>
      <!-- 旧:javax.persistence.jdbc.url -->
      <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://db:5432/app"/>
      <property name="jakarta.persistence.jdbc.user" value="app"/>
    </properties>
  </persistence-unit>
</persistence>

スキーマと違い、プロパティ名は仕様上の名前そのものが変わっています。旧名を互換のために受け付けるかどうかは実装ごとに異なり、それに頼ると次の版上げで同じ確認をやり直すことになります。application.propertiesにjavax.persistenceで始まる設定を書いている場合も同じ扱いです。

ソースを直せない部品だけをTomcat移行ツールでWARごと変換する場面

移行ツール1.0.13のprofileとexcludeでWAR内の変換対象を絞る指定

ソースが手元に無い社内ライブラリや、提供元が更新を止めた部品は、ビルド済みのWARを変換する方法をとります。Tomcat Migration Tool for Jakarta EEの最新版は1.0.13です。基本の変換コマンドと配備時の自動変換はTomcatのバージョン一覧とサポート期限で扱ったので、ここでは変換範囲の指定に絞ります。

# 既定の TOMCAT は Tomcat が提供する API だけを変換する。JMS や EJB も含めるなら EE を指定する
java -jar jakartaee-migration-1.0.13-shaded.jar -profile=EE app.war app-jakarta.war

# 変換済みの JAR や署名を残したい JAR を除外する(複数回指定でき、大文字小文字を区別する)
java -jar jakartaee-migration-1.0.13-shaded.jar -exclude=bcprov-*.jar app.war app-jakarta.war

# 一部の zip 構造で例外が出たときは、メモリ上で処理させる
java -jar jakartaee-migration-1.0.13-shaded.jar -zipInMemory app.war app-jakarta.war

READMEによると、変換したJARの暗号署名は外されます。署名を検証する暗号ライブラリなどは-excludeで外しておかないと、起動時に検証で失敗します。変換対象はJava EEで定義されたパッケージだけなので、ツールを通してもJDKのjavaxは変わりません。

Spring Bootの実行可能JARは変換ツールに頼らずソース移行を選ぶ理由

WAR変換が向くのは、外部のTomcatへ配備するWARです。Spring Bootの実行可能JARは組み込みTomcatを中に持ち、Spring Boot 3以降の組み込みTomcatはjakartaの実装です。外部TomcatのlegacyAppBaseによる配備時変換は使えず、依存JARを後から変換すると、Spring Boot自体の版と合わない構成が残ります。

Spring Bootのアプリは、ソースと依存を正面から移行する方針をとります。変換ツールは、ソースの無い部品を1つずつ処理する用途に限ります。

Spring Boot 2から3への同時移行の順序と一括で進めない場面の判断

2.7系の最新版とJava 17を先に固めてから3系へ上げる公式の順序

Spring Boot 3.0の移行ガイドは、移行の前に2.7系の最新版へ上げることを勧めています。Spring Boot 3.0はJava 17以降が必須で、依存する仕様はJakarta EE 10(Servlet 6.0・JPA 3.1)に上がり、Hibernateは6.1が既定になりました。Spring Securityは5.8を経由する手順が示されています。

  1. Spring Boot 2.7系の最新版へ上げ、テストを通す
  2. JDKを17以降へ上げ、2.7系のまま動作を確かめる
  3. Spring Securityを5.8へ上げ、非推奨の警告を解消する
  4. Spring Boot 3系へ上げ、OpenRewriteでjavaxを書き換える
  5. spring-boot-properties-migratorを一時的に入れ、名前の変わった設定を起動ログで洗い出す

1度に変える要素を1つにしておくと、テストが落ちたときに原因の切り分けが速くなります。JDKの更新とjakarta化を同じコミットに入れないのが、この順序を守る意味です。Spring Boot 4系との差分はSpring Boot 4の変更点とSpring Boot 3との違い、JDKの更新手順はJavaマイグレーションの進め方で扱っています。

jakarta対応版の無い部品が残る場合に移行を止めて9.1系で待つ条件

依存ツリーの確認で、jakarta対応版の無い部品が見つかることがあります。帳票、認証、PDF生成などの商用ライブラリが典型です。この部品が業務の中心にあり、提供元が対応版の予定を示しているなら、Tomcatを9.1系へ切り替えて待つ判断を採ります。9.1系は2030年12月31日までリリースが続く予定です。

逆に、提供元の更新が止まっている部品なら、待っても状況は変わりません。WAR変換で動くかを検証環境で試し、動かなければ置き換え先の選定を移行計画の最初に置きます。対応版の予定が無い部品のために移行全体を止める選択は採りません。部品の棚卸しから置き換え、回帰テストまでを外部に任せたい場合は、システムマイグレーション・リプレイスで既存システムの移行計画から相談を受けています。

よくある質問

javaxからjakartaへの移行について、検索の多い質問に答えます。

javaxをjakartaに一括置換するだけで移行できますか?

できません。javax.sqlやjavax.transaction.xa、javax.cryptoはJDKのパッケージで、書き換えるとコンパイルが通らなくなります。また、依存ライブラリが旧APIを使っていれば、自分のコードを直しても新旧が混在する状態です。依存の差し替え、OpenRewriteによる構文を理解した書き換え、grepによる残りの確認の順に進めます。

Tomcat 10でjavaxのアプリを動かすことはできますか?

そのままでは動きません。Tomcat 10系以降はjakartaのAPIを実装しているため、javax.servletのクラスを読み込めないからです。短期的には、Tomcat移行ツールでWARを変換するか、10.1系・11.0系のlegacyAppBaseに置いて配備時に変換させる方法があります。恒久的にはソースと依存を移行します。

javax.annotationもjakartaに変える必要がありますか?

@PostConstruct・@PreDestroy・@Resourceなど、Java EEのCommon Annotationsに属するものはjakarta.annotationへ移ります。Maven座標はjakarta.annotation:jakarta.annotation-apiで、Jakarta EE 11に合わせるなら3.0.0です。一方、JDKのjavax.annotation.processingはアノテーションプロセッサ用のAPIで、移行の対象外です。

Spring Boot 2からSpring Boot 3へ上げるとjakarta化は必須ですか?

必須です。Spring Boot 3.0はJakarta EE 10の仕様に依存しており、javax.servletやjavax.persistenceのAPIは使えません。移行ガイドは、先に2.7系の最新版へ上げ、Java 17以降にしてから3系へ進む手順を示しています。書き換えにはOpenRewriteのレシピやIDEの移行機能が使えます。

Tomcatの移行ツールとOpenRewriteはどちらを使えばよいですか?

ソースがあるならOpenRewriteを使います。ソースと依存そのものを書き換えるため、移行後に保守するコードもjakartaに揃う仕組みです。Tomcatの移行ツールはビルド済みのWARやJARを変換するもので、ソースの無い部品や、移行前に動作を確かめる検証用途に向きます。本番の成果物は、ソースを移行してビルドしたものに置き換えていきます。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.03 テックブログ ノジマ不正アクセスで約700万件漏えい:対象確認・窓口と乗っ取り注文を止める実装
  2. 2026.10.29 テックブログ ソニー生命の情報漏洩38.5万件|ログインできない理由、再開状況と窓口の電話番号
  3. 2026.11.03 テックブログ クラブツーリズム不正アクセス:約432万件の対象確認と偽メールの見分け方・流出検知の設計
  4. 2026.11.02 テックブログ アララの不正アクセス:メール約7,700万件の持ち出しと契約企業が行うAPIキー再設定・代替送信・連名報告
  5. 2026.11.02 テックブログ サントリーの不正アクセスで約10万人分漏えい|M365のファイル大量ダウンロードを監査ログで調べる手順

RELATED POSTS 関連記事

目次