これは Jakarta EE / Java EE Advent Calendar 2025 の14日目の記事です。
7月末に行われた JakartaOne Japan 2025 において、Jakarta変換ツールについて検証・発表した内容を記事化します。
以下の資料と合わせてみることで理解が深まると思います。
発表した際の資料
Jakarta変換とは?
Oracleが管理していたJava EEがEclipse Foundationに移管され、名称がJava EEからJakarta EEに変わり、名前空間の変更が行われました。
詳しい背景についてはこちらをご覧ください。
https://blogs.oracle.com/otnjp/transition-from-java-ee-to-jakarta-ee-ja
そして、Java EEからJakarta EEに移行する際は主に以下の2点を修正する必要があります。
- パッケージ名の変更
- Deployment Descriptorのバージョンアップ
※加えて、各仕様固有の非互換対応が必要になります。そちらについては各仕様のドキュメントをご参照ください。
上記2点について、それぞれ詳しく説明します。
パッケージ名の変更
管理元が変わったことで、Java EEのAPIが使用していた主要なパッケージ名(javax.*)がJakarta EEでは新しいパッケージ名(jakarta.*)へと変更されました。
この変更は、単なる名前の置き換えにとどまらず、アプリケーションのソースコード、ライブラリ、および設定ファイル全体に影響を及ぼします。
例えば、javax.servlet.Servletはjakarta.servlet.Servletに、javax.ejb.Statelessはjakarta.ejb.Statelessに変更されます。
このパッケージ名の変更は、特に大規模な既存のJava EEアプリケーションにとって大きな課題となります。
依存するサードパーティライブラリがまだJakarta EEに対応していない場合、アプリケーション自体をJakarta EEに変換しても、ライブラリの互換性の問題に直面することがあります。
変換ツールは、このjavax.*からjakarta.*への自動的な置換を主な機能として提供し、開発者の負担を軽減します。
Deployment Descriptorのバージョンアップ
Deployment Descriptor(以降、DD)と呼ばれる、 web.xml や ejb-jar.xml 、 application.xml などのXMLファイルは、Enterprise Javaにおいてアプリケーションの構成やデプロイに関する情報を含んでいます。
Jakarta EEへの移行に伴い、これらのXMLスキーマのバージョンも更新する必要があります。
例えば、ServletのDDであるweb.xmlの場合、
Java EEまでは通常xmlns="http://xmlns.jcp.org/xml/ns/javaee"やversion="4.0"が使用されていましたが、
Jakarta EE 9以降ではxmlns="https://jakarta.ee/xml/ns/jakartaee"やversion="5.0"(あるいはそれ以降のバージョン)に変更する必要があります。
このバージョンアップは、XMLスキーマのURLだけでなく、DTD(Document Type Definition)やXSD(XML Schema Definition)ファイルへの参照自体が変更されることを意味し、手動での修正は非常に手間がかかる作業となります。
変換ツールは、これらのDD内のスキーマ定義やバージョン情報を自動的に更新する機能も有しています。
ちなみに、どんなDDが使用できるかはアプリケーションサーバーによりますが、GlassFishではソースコードから使用可能なDDを確認することができます。
https://github.com/eclipse-ee4j/glassfish/tree/master/appserver/deployment/schemas/src/main/resources/glassfish/lib/schemas
Java EE時代のGlassFishを見ることで、古いDDのバージョンも確認できます。
https://github.com/javaee/glassfish/tree/master/appserver/deployment/schemas/src/main/resources/glassfish/lib/schemas
スキーマが古いと使用している機能が削除されていることがあるためスキーマを古いままにすることはアプリケーションが動かなくなるリスクを抱えることになります。
具体的には、古いスキーマバージョンのDDは新しいJakarta EE仕様で追加された機能に対応できないため、これらの新機能を使用する場合はDDの更新が必須です。
一方、アプリケーションが既存のJava EE機能のみに依存している場合、かつ利用しているアプリケーションサーバーが古いスキーマをサポートしていれば、DDの更新は必須ではないケースもあります。
しかしながら、将来的な互換性やセキュリティの観点から、可能な限り最新のスキーマに更新することを推奨します。
主要なツールには何があるのか?
Jakarta変換機能を持つツールは分析機能を持っているものも多いですが、ほとんどが商用版です。

(発表資料の14ページ目 より引用 )
今回は、変換機能のみを持つ左の3つのツールに焦点を当てて比較を行いました。
Apache Tomcat migration tool
Tomcatの移行ツールとして用意されている変換ツールです。
ソースコードは以下から確認できます。
https://github.com/apache/tomcat-jakartaee-migration
内部の処理は特定の文字列を検出し置換する構造になっています。
単純な文字列置換なのでビルド済みのバイナリ資材も変換できます。
このツールはそのまま使用するとWebプロファイル専用の変換ツールですが、プロファイルの指定をすることでWebプロファイル以外の変換も行えます。
内部の変換ルールのわかりやすさも、変換のブラックボックス化を回避し保守性を向上するという観点で重要なので紹介します。
以下のソースを見ると内部で何が変換されるのかわかります。
https://github.com/apache/tomcat-jakartaee-migration/blob/main/src/main/java/org/apache/tomcat/jakartaee/EESpecProfiles.java
例:TOMCATを指定する場合
TOMCAT("javax", "jakarta",
"javax([/\\.](annotation[/\\.](" + Patterns.ANNOTATION_CLASSES + ")" +
"|ejb" +
"|el" +
"|mail" +
"|persistence" +
"|security[/\\.]auth[/\\.]message" +
"|servlet" +
"|transaction(?![/\\.]xa)" +
"|websocket))"),
例:EEを指定する場合
/**
* Specification profile for the full EE.
*/
EE("javax", "jakarta", "javax" + Patterns.EE),
~~~
static final String EE = String.join("|",
Arrays.asList(
"([/\\.](activation",
"annotation[/\\.](" + ANNOTATION_CLASSES + ")",
"batch",
"decorator",
"ejb",
"el",
"enterprise",
"faces",
"jms",
"json",
"jws",
"interceptor",
"inject",
"mail",
"management[/\\.]j2ee",
"persistence",
"resource",
"security[/\\.](auth[/\\.]message|enterprise|jacc)",
"servlet",
"transaction(?![/\\.]xa)",
"validation",
"websocket",
"ws[/\\.]rs",
"xml[/\\.](bind|soap|ws)))"
));
Eclipse Transformer
Eclipse Transformerは、Jakarta EEの開発プロジェクトと同様にEclipse FoundationがホストしているOSSの変換ツールです。
ソースコードは以下から確認できます。
https://github.com/eclipse-transformer/transformer
また、Eclipse Foundationでも案内されています。
https://projects.eclipse.org/projects/technology.transformer
Eclipse TransformerもApache Tomcat MTと同じように単純な文字列置換を行います。同じようにバイナリ資材の変換もできます。
また、以下から確認できますが変換ルールもわかりやすいです。
https://github.com/eclipse-transformer/transformer/blob/main/org.eclipse.transformer.jakarta/src/main/resources/org/eclipse/transformer/jakarta/jakarta-direct.properties
# Jakarta Server Pages string constants from jakarta.servlet.jsp-api-2.3.6.jar
javax.servlet.jsp.jspApplication=jakarta.servlet.jsp.jspApplication
javax.servlet.jsp.jspConfig=jakarta.servlet.jsp.jspConfig
javax.servlet.jsp.jspException=jakarta.servlet.jsp.jspException
javax.servlet.jsp.jspOut=jakarta.servlet.jsp.jspOut
javax.servlet.jsp.jspPage=jakarta.servlet.jsp.jspPage
javax.servlet.jsp.jspPageContext=jakarta.servlet.jsp.jspPageContext
javax.servlet.jsp.jspRequest=jakarta.servlet.jsp.jspRequest
javax.servlet.jsp.jspResponse=jakarta.servlet.jsp.jspResponse
javax.servlet.jsp.jspSession=jakarta.servlet.jsp.jspSession
こちらでは、javax.servlet.jsp.jspApplicationはjakarta.servlet.jsp.jspApplicationに変換するというルールが決められています。
単純なjavaのプロパティの構文でルールを策定できるため、変換ルールのカスタマイズや確認がしやすいという強みがあります。
OpenRewrite
元々はJava専用の変換ツールだったのが、いろいろ裾野を広げて汎用的な変換ツールとなった強力なツールです。
ソースコードは以下から確認できます。
https://github.com/openrewrite/rewrite
また、こちらは公式サイトが存在します。
https://docs.openrewrite.org/
こちらのツールは単純な文字列置換ではなく、ソースコードを一度LSTと呼ばれるデータ構造に変換し、そのLSTを独自リソースであるレシピを使用して変換、そしてLSTをjavaファイルに復元します。
詳しくは公式の説明をご覧ください。
https://docs.openrewrite.org/concepts-and-explanations/lossless-semantic-trees
このLSTを用いた変換というのがやや強力で、ソースコードの構文を維持したまま変換を行うことができます。
前に説明した文字列置換と比較しながら説明します。
LSTを用いた変換を行うと、構文というものを抽象化し作用させることができます。
つまり、Javaの構文が守られたまま変換を行うため、変換の前後で構文の正しさが保証されます。
文字列置換の場合、完全一致する文字列を抽出し変換を行うため、構文の正しさが保証されません。ここがLSTを用いた変換の大きな強みです。
今回のJakarta変換に限って言えば構文に関わる変換はないため単純な文字列の置換で十分です。
ただしAPIの使用方法の変更といったような、構文に関わる変換を行いたい場合は構文の正しさの保証が重要になります。
前2ツールで言及していた変換ルールの理解しやすさという観点では、前2ツールと比較するとやや難しいです。
例えばJakarta EE 9に変換する際のレシピのソースは以下です。
https://github.com/openrewrite/rewrite-migrate-java/blob/main/src/main/resources/META-INF/rewrite/jakarta-ee-9.yml
レシピには独自の構文があり、org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakartaというレシピはrecipeListにある大量のレシピを内包しています。
それらのレシピのうちの一つのorg.openrewrite.java.migrate.jakarta.JavaxActivationMigrationToJakartaActivationについては同ファイル内に定義があります。
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.migrate.jakarta.JavaxActivationMigrationToJakartaActivation
displayName: Migrate deprecated `javax.activation` packages to `jakarta.activation`
description: Java EE has been rebranded to Jakarta EE, necessitating a package relocation.
tags:
- activation
- javax
- jakarta
recipeList:
- org.openrewrite.java.dependencies.ChangeDependency:
oldGroupId: javax.activation
oldArtifactId: javax.activation-api
newGroupId: jakarta.activation
newArtifactId: jakarta.activation-api
newVersion: 2.0.x
- org.openrewrite.java.dependencies.UpgradeDependencyVersion:
groupId: com.sun.activation
artifactId: jakarta.activation
newVersion: 2.0.x
- org.openrewrite.java.dependencies.UpgradeDependencyVersion:
groupId: jakarta.activation
artifactId: jakarta.activation-api
newVersion: 2.0.x
- org.openrewrite.java.ChangePackage:
oldPackageName: javax.activation
newPackageName: jakarta.activation
recursive: true
ここでようやく、JavaxActivationMigrationToJakartaActivationというのが何をどう変換するのかがわかります。
このように、OpenRewriteという「汎用性の高さ」の特性上、どうしても変換ルールを決める際には少し複雑な変換ルールの構文に従う必要があり、
それゆえに自分で手を加えるのに手間がかかったり理解に苦労したりします。
変換ツールの比較・検証
比較・検証についてはスライドに詳しく書いています。そちらをご覧ください。
https://speakerdeck.com/kaido207/30-jakartaone-japan-2025-jakartaeeyi-xing-zhan-lue?slide=19
※スライドの19~31
結論
ツールによって対応範囲や特性が異なるため、ユースケースごとに使い分けることを推奨します。
スライドにも書いていますが、
- バイナリ変換をしたい⇒Apache Tomcat MTかEclipse Transformer
- 手広く変換したい⇒OpenRewrite
- 分析もしたい⇒Konveyor、また各ベンダーの分析ツールを検討
という選び方になるのかなと思います。