LastaFluteのJakarta対応 (Java21)

Jakarta対応しました。(Java21コンパイル、Tomcat10対応、Servlet6対応)

そもそもJakarta対応とは?

Java標準のフレームワークであった JavaEE が、オープンソースコミュニティ Eclipse Foundation に寄贈され、JakartaEE というオープンソースとして生まれ変わりました。

その際、javax.始まりのパッケージが、jakarta.始まりのパッケージに変わるなど、利用者が意識せざるを得ない修正が入りました。 そして、多くのフレームワークがJavaEEの一部機能を利用しているため、JavaEEを使っていない開発者にも大きな影響があります。

Jakarta Servlet
Tomcatそのもの、多くのWebフレームワークが利用
Jakarta Annotation
LastaFluteでよく使っている@Resourceアノテーション
Jakarta Transaction
Lasta Diでよく使っているTransactionの仕組み
Jakarta Mail
MailFluteで使っているJavaにおける基本のメールエンジン
など
など

ゆえに、(ほぼ)どのフレームワークも、互換性を崩してJakarta対応をしたバージョンを提供しないといけなくなりました。 LastaFluteもその一つです。

Jakarta版LastaFlute

LastaFluteのライブラリは、全体的に 2.0.0 以降がJakarta対応です。

リリース一覧

LastaFlute
2.0.0 (2024/08/21)
Lasta Di
2.0.0 (LastaFlute組み込み) (2024/08/21)
MailFlute
2.0.0 (LastaFlute組み込み) (2024/08/21)
Lasta Job
2.0.0 (2024/08/21)
Lasta Thymeleaf
2.0.0 (2024/08/21)
Lasta RemoteApi
2.0.0 (2024/08/21)
Lasta Meta
2.0.0 (2024/08/21)
Lasta Taglib
2.0.0 (2024/08/21)
JettyBoot
2.0.0 (まだ)
TomcatBoot
2.0.0 (2024/08/21)
UTFlute
2.0.0 (2024/08/21) // spring,guice,seasarは除外

Java8版との整合性

しばらくは、Java8版と機能面での差は出さないような運用をしていきます。(2024/08/04)

新機能や修正は、Java8版で実装してからJakarta版にマージしていきます。

masterブランチ
Java8版
developブランチ
Java8版
jakartaブランチ
Jakarta版 (Java21)

exampleやtestも

exampleやtestプロジェクトもブランチで分けてマージ管理していきます。

masterブランチ
Java8版でJava8実行 (必須)
javax11ブランチ
Java8版でJava11実行 (あったりなかったり)
javax17ブランチ
Java8版でJava17実行 (あったりなかったり)
javax21ブランチ
Java8版でJava21実行 (あったりなかったり)
jakarta21ブランチ
Jakarta版でJava21実行 (必須)

依存ライブラリをJakartaに

Jakarta版に移行するにあたって、LastaFluteが依存(利用)している周辺ライブラリもJakarta対応のバージョンに変更する必要があります。

依存スコープに夜じゃなくて寄る

LastaFluteやLastaライブラリがcompileスコープやruntimeスコープで依存しているものに関しては、アプリで意識しなくても推移的依存で解決されます。

providedスコープやoptionalで指定されている "列挙ライブラリ" は、アプリ側で設定する必要があります。 (アプリで列挙する必要があるので、ここでは列挙ライブラリと呼ぶこととします)

列挙ライブラリのJakartaバージョン

主な列挙ライブラリは以下の通りです。

Servlet
jakarta.servlet:jakarta.servlet-api:6.0.0 (まあ必須)
Annotation
jakarta.annotation:jakarta.annotation-api:2.1.1 (まあ必須)
JTA
jakarta.transaction:jakarta.transaction-api:2.0.1 (そりゃ必須)
FileUpload
org.apache.commons:commons-fileupload2-jakarta-servlet6:2.0.0-M2
JAXB
jakarta.xml.bind:jakarta.xml.bind-api:4.0.2

バージョンは執筆時点の最新版で、LastaFluteが開発時に参照しているバージョンです。 アプリ側でこれより高いバージョンにするのは、(互換性が崩れていなければ)多くの場合は問題ないでしょう。

まあ必須、そりゃ必須の意味がわからないと思います。状況に寄って必須かどうかは変わりますので、この後の詳細を読みましょう。

Jakarta Servlet (まあ必須)

TomcatやLastaFluteががっつり利用しているクラスが含まれるライブラリで、LastaFluteを動かすには必須です。

ですが、Tomcatに組み込まれていますので、TomcatBootをcompileスコープで依存しているプロジェクトでは依存定義は不要になります。 一方で、マルチプロジェクト構成の(Tomcat非依存でもweb依存の)commonプロジェクトでは必要になります。 実際に実行される環境はTomcatなのでcommonプロジェクトだけでprovided依存を定義すればOKです。

ただ、その辺を細かく意識していくのは大変ではありますので、Tomcat依存してるかどうか気にせず一律全体的にprovided依存しても大きな問題にはなりにくいとは思います。 (providedなのでwarファイルに含まれるわけではないですし、バージョンがズレてもそこまで大きな変化は考えにくいので)

  • LastaFluteで想定しているServletのバージョン (TomcatのServletよりも古い可能性)
  • アプリで利用したいServletのバージョン (新しいServletのメソッド使いたいか?)
  • Tomcatに組み込まれてるServletのバージョン (実際にアプリ実行時に参照されるServlet)

これらバージョンをどう制御したいかに寄って、アプリでの依存定義の仕方を変えると良いでしょう。

Jakarta Annotation (まあ必須)

@Resourceアノテーションなど Lasta Di がよく利用しているアノテーションが含まれるライブラリで、LastaFluteを動かすには必須です。

基本的には、Servletと同じ話になります。

一方で、Java8環境ではJava標準に組み込まれていて定義が不要だったので、Jakarta版に移行すると同時にJavaのバージョンもJava9以降にする場合は、新しく依存定義を追加することになるでしょう。

一方で一方で、Jakarta Annotationを組み込んでない他のアプリサーバーを使っているプロジェクトの場合は、compileスコープでの依存が必要になるでしょう。(やったことないのですが...)

JTA (transaction) (そりゃ必須)

TransactionManagerなど Lasta Di がよく利用しているクラスが含まれるライブラリで、LastaFluteを動かすには必須です。

こちらは組み込みTomcatにも含まれていないので、Tomcat使ってるプロジェクトなら依存定義は必要になります。 compileスコープで定義するとよいでしょう。(マルチプロジェクトなら全体的に一律で)

一方で、JTAが含まれているアプリサーバーなら、扱い的にはServletと似た感じになるはずです。

Commons FileUpload

こちらはLastaFlute自体は直接利用するわけではありませんが、アプリでファイルアップロードをする際に手軽に利用できるライブラリということで、exampleプロジェクトで参考実装として使っているものです。

ファイルアップロードをしているのであれば、exampleプロジェクトを参考に定義と実装を用意しましょう。

JAXB (xml)

こちらは Lasta RemoteApi が optional として依存しているもので、リモートサーバーとXMLでのやり取りするときに依存定義が必要になります。

XMLがどうしても必要になったときに定義しましょう。

そもそもJava8からJava21の移行

Jakarta対応関係なく、アプリの環境をJava8からJava21にアップグレードすることによる影響がありますので、その代表的なものを列挙しておきます。 (Jakarta対応せずに、Java8版のLastaFluteをJava21環境で動かす場合もこちらが必要です)

@Resourceを追加

Java9より、@Resourceアノテーションを提供している javax.annotation がJava標準から外れました。ゆえにアプリがJava9以降の場合は明示的に依存定義を追加する必要があります。

LastaFluteが、Jakarta版なら jakarta.annotation, Java8版なら javax.annotation となります。

@XmlElementを追加 (必要なら)

Java9以降のどこかにより、@XmlElementを提供しているJAXBがJava標準から外れました。 ゆえにアプリがJava9どこか以降の場合で、Lasta RemoteApi で XML の機能を利用している場合は、明示的に依存定義を追加する必要があります。

saiを追加 (必要なら)

Java15より、Javaに組み込まれていたJavaScriptエンジンのNashornがJava標準から外れました。 ゆえにアプリがJava15以降で、Di xmlでJavaScriptの記法を使っている場合は、saiの依存定義を追加する必要があります。

DBFluteをJakartaに

DBFluteが自動生成するクラスでJakartaクラスを参照している箇所があります。 デフォルトではjavaxパッケージでの参照になっているので、Jakarta環境ではコンパイルエラーになります。

littleAdjustmentMap.dfpropにて、isMigrateOldJavaxToJakartaをtrueにするとjakartaパッケージでの参照になります。

e.g. DBFluteの自動生成クラスをjakarta対応させる @littleAdjustmentMap.dfprop
...
# o relationalNullObjectMap: (NotRequired - Default map:{})
# o cursorSelectFetchSize: (NotRequired - Default null)
# o refreshMap: (NotRequired - Default map:{})
# o optimisticLockMap: (NotRequired - Default map:{})
#
# *The line that starts with '#' means comment-out.
#
map:{
    # to use #jakarta package on generated classes by DBFlute
    ; isMigrateOldJavaxToJakarta = true

    # /- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # o isAvailableAddingSchemaToTableSqlName: (NotRequired - Default false)
...

LastaFluteのexampleにて利用されていますので参考に。

一応、専用のページあります。

FreeGenのFluteたちは?

KVSFlute や RemoteApiGen たちは?

FreeGenFluteの対応リスト

KVSFlute
2024/08/05時点で未対応
RemoteApiGen
2024/08/05時点で未対応

対応でき次第、情報を更新していきます。

自分でFreeGenテンプレート修正する方法

未対応であっても、FreeGenのテンプレートは目の前にありますので、修正することはそこまで難しくはありません。

e.g. RemoteApiGenのアノテーションをjakarta対応させる @Velocity
#set($added = $importList.add('javax.validation.constraints.NotNull'))
 ↓↓↓
#set($notNullAnnotation = ${manager.currentJakartaPackage} + '.validation.constraints.NotNull')
#set($added = $importList.add(${notNullAnnotation}))

...

#generateIndent($nestList.size())@javax.validation.Valid
 ↓↓↓
#generateIndent($nestList.size())@${manager.currentJakartaPackage}.validation.Valid
e.g. RemoteApiGenのRemoteApiRule.jsをjakarta対応させる @Velocity
     importOrderList: function() {
         return ['java', 'javax', 'junit', 'org', 'com', 'net', 'ognl', 'mockit', 'jp'];
     },
 ↓↓↓
     importOrderList: function() {
         return ['java', 'javax', 'jakarta', 'junit', 'org', 'com', 'net', 'ognl', 'mockit', 'jp'];
     },

いざとなったら、こういう要領で直すと良いでしょう。

ただし、manager.currentJakartaPackage は、DBFlute-1.2.7から利用可能なメソッドなので、それより古い場合はDBFluteを最新にアップグレードしましょう。