Nashornからsaiへの移行

概要

LastaFluteでNashornを使ってるところ

Java組み込みのJavaScriptエンジン Nashorn というものがあります。

LastaFluteでは、以下の状況で使っています。

LastaFlute向けのFreeGen
LastaDocやRemoteApiGenで使っている (JSONの書き出しなど)
Lasta Di の Di xml
複雑なスクリプト表現で使っている

NashornがJava15から外された

ですが、その Nashorn が Java15 より外されて、デフォルトでは利用できません。

(なので、Java15以上の環境で、FreeGenを実行したり、Lasta Di を起動したりすると落ちます)

Nashornをforkしたsaiが登場

Nashornをforkした sai というライブラリが利用できます。

Github
https://github.com/codelibs/sai

saiはJava11でコンパイルされているので、Java11以降の環境であれば利用できます。 (Java8の環境の場合は、そもそもsaiを利用する必要がありません)

FreeGen環境のsai移行

以下のような流れで移行できます。

  1. DBFlute を 1.2.4 以上にアップグレードする
  2. sai の jarファイルたちをダウンロードする
  3. extlib に sai の jarファイルたちを配置する

DBFlute-1.2.4より sai を有効に

DBFlute-1.2.4 より、クラスパスに sai が存在すれば sai を利用するようにしました。

なので、まずはDBFluteを最新版にアップグレードをしましょう。

sai の jarファイルたちをダウンロード

まず、sai-0.2.0においては、全部で6つのjarファイルのダウンロードが必要です。

  • asm-7.1.jar
  • asm-analysis-7.1.jar
  • asm-commons-7.1.jar
  • asm-tree-7.1.jar
  • asm-util-7.1.jar
  • sai-0.2.0.jar

もし、DBFlute-1.2.5 patch 2021/08/29 以降なら

saiタスクを使って移行できます。

manageタスクの 31 (sai) を実行して jarファイルたちをextlibにダウンロードしましょう。

これで終了です。FreeGenを実行できます。

もし、手作業ダウンロードなら

mvnrepository のサイトに、jarファイルへのダウンロードリンク (Files の jar) が貼られていますので、そこからそれぞれダウンロードすることができます。

asm
https://mvnrepository.com/artifact/org.ow2.asm/asm/7.1
asm-analysis
https://mvnrepository.com/artifact/org.ow2.asm/asm-analysis/7.1
asm-commons
https://mvnrepository.com/artifact/org.ow2.asm/asm-commons/7.1
asm-tree
https://mvnrepository.com/artifact/org.ow2.asm/asm-tree/7.1
asm-util
https://mvnrepository.com/artifact/org.ow2.asm/asm-util/7.1
sai
https://mvnrepository.com/artifact/org.codelibs/sai/0.2.0

もし、Mavenのcopy-dependenciesなら

バージョン合わせてのダウンロードが面倒だと思われる方は、Mavenなどのビルドツールを一時的に利用してダウンロードする方法でも良いでしょう。 (jfluteはいつもこうしてます)

例えば Maven であれば、pom.xmlにsaiのdependencyを追加して...

e.g. pom.xmlにsaiのdependencyを追加 @Xml
<dependencies>
    ...

    <dependency>
        <groupId>org.codelibs</groupId>
        <artifactId>sai</artifactId>
        <version>0.2.0</version>
    </dependency>

    ...
</dependencies>

copy-dependencies を実行すると、(デフォルトであれば)target/dependency配下にjarファイルがダウンロードされます。

e.g. 依存ライブラリをすべてダウンロードするMavenコマンド @Command
mvn dependency:copy-dependencies

※ちなみに、「そもそも DBFlute Engine に組み込めば?」と思われるかもですが、ライセンス的に組み込めません。

DBFluteクライアントのextlibに配置

DBFlute Engineの実行クラスパスにjarファイルを追加することのできる "DBFluteクライアントの extlib ディレクトリ" に、sai のjarファイルたちを配置します。

e.g. DBFluteクライアントの extlib に sai を配置 @Directory
dbflute_maihamadb
 |-dfprop
 |-...
 |-extlib
 |  |-asm-7.1.jar
 |  |-asm-analysis-7.1.jar
 |  |-asm-commons-7.1.jar
 |  |-asm-tree-7.1.jar
 |  |-asm-util-7.1.jar
 |  |-sai-0.2.0.jar
 |-...
 |-log

これにて、LastaFluteのFreeGenは、saiを使って実行するようになります。

DBFlute Engineのソースコードで関連するクラスは、DfFrgJavaScriptJsonEngineです。

jarをgitにコミットするかしないか?

どちらも大丈夫です。プロジェクトの都合に合わせましょう。

gitにコミットする
他の人は配置作業せずにFreeGenが実行できる
gitignoreにする
他の人もダウンロードして配置する必要あるが、gitは軽くなる

_project.shでJava11指定にした方が良い?

もし、MacOSのPCでJava8も同時にインストールされている環境であれば、_project.sh の設定次第でJava8が優先利用されてsaiが動かない可能性があります。(saiはJava11)

そのときは、_project.sh の JAVA_HOME の設定を変更すると良いでしょう。

DBFluteをアップグレードできない場合

どうしてもDBFluteをアップグレードできない場合は、Nashornのjarファイルたちをextlibに配置すると動くかもしれません。 (ただ、試したことはないです)

Lasta Diのsai移行

いま起動しても落ちないのであれば?

まず、Java15以降でLastaFluteのプロジェクトを起動して落ちていないのであれば、ひとまず移行はしなくても良いかもしれません。

Lasta Di の新しいバージョンでは、Lasta Di内部で使っている Di xml では、JavaScript表現を使わないように修正されています。 なので、アプリケーションの中の Di xml でJavaScript表現を使わない限り sai を入れる必要はありません。

Di xmlは起動時にすべて読み込まれますから、起動して落ちていないということはアプリケーションでも使っていない可能性が高いです。 そもそも、Di xml でJavaScript表現を使うことは稀です。

いま起動で落ちるのであれば?

まずは、Lasta Di (LastaFlute) を最新版にアップグレードしましょう。

先の通り、Lasta Di の新しいバージョンでは、内部の Di xml でJavaScript表現を使わないようにしているので、アップグレードするだけで解決するかもしれません。

アップグレードしても落ちる(アプリでJavaScript表現を使っている)、もしくは、アップグレードがどうしてもできないのでれば、saiを入れましょう。

saiを依存ライブラリに追加

例えば Maven であれば、pom.xmlにsaiのdependencyを追加します。

e.g. pom.xmlにsaiのdependencyを追加 @Xml
<!-- javascript engine (instead of nashorn)
 you can get the jar files including dependencies by mvn dependency:copy-dependencies
 -->
<dependencies>
    <dependency>
        <groupId>org.codelibs</groupId>
        <artifactId>sai</artifactId>
        <version>0.2.0</version>
    </dependency>
</dependencies>

lasta_di.properties に sai を設定

Lasta Di-0.8.5 (LastaFlute-1.2.2) 以降なら

クラスパスに sai があれば sai を利用するので、lasta_di.properties の設定は不要です。

Lasta Di-0.8.4 (LastaFlute-1.2.1) までなら

lasta_di.properties に、dixml.script.managed.engine.nameプロパティを追加して、sai を設定しましょう。

e.g. lasta_di.properties に sai を設定 @Xml
# name of engine managed by Lasta Di for script on Di xml
dixml.script.managed.engine.name = sai

これにて Lasta Di は、JavaScript表現が必要なときに sai を使うようになります。

Lasta Diのソースコードで関連するクラスは、JavaScriptExpressionEngineです。

もしかしたら、将来の Lasta Di では、この properties の設定をしなくてもデフォルトで sai を使うようになるかもしれません。 (sai あれば使う、なければ Nashorn を探す、というようなロジックにするかも。ただ、どのみちMavenやGradleなどの依存ライブラリには追加しないといけません)

念のため、ライセンスに注目

Sai は The GNU General Public License ("CLASSPATH" EXCEPTION) です。

いわゆる GPL に "CLASSPATH" EXCEPTION が付いています。 開発しているアプリケーションの配布形式など、ライセンスが適合するか確認するようにしてください。

(DBFluteクライアントのextlibに関しては、DBFlute Engineも含めてまるごと配布するようなアプリでなければ、特に問題はないと思われます。 また、Lasta Diのクラスパスに関しては、アプリケーションのwarファイルをまるごと配布するようなアプリでなければ、特に問題はないと思われます。ただ、アプリケーション側で確認はして、自己責任で判断してください)

ASMは 3-Clause BSD License です。