jiichan.com

PROGRAMMING

Java
javascript
CSS
PHP

IntelliJ.Gradle.JavaFX (3) Jlink でカスタム JRE を作る

ライブラリなどを含んだ Fatjar も実行するためにはJavaランタイムが必要です。
そこで、実行するための必要最低限のJREをJlinkで作ります。
テスト用プロジェクトはtestFatjarにしました。

開発環境
IntelliJ IDEA 2021.2.2 (Community Edition)
jdk-15.0.1
javafx-sdk-15.0.1
javafx-jmods-15.0.1

jdeps コマンドで必要なモジュールを知る

実行可能jarで必要なモジュールを確認するために、jdepsコマンドをターミナルで実行します。
-s オプションは依存関係のサマリー(要約)のみを出力します。

> jdeps -s build\libs\testFatjar-1.0-all.jar
testFatjar-1.0-all.jar -> java.base
testFatjar-1.0-all.jar -> java.desktop
testFatjar-1.0-all.jar -> java.scripting
testFatjar-1.0-all.jar -> java.xml
testFatjar-1.0-all.jar -> jdk.jfr
testFatjar-1.0-all.jar -> jdk.unsupported

何故かjavaFxの分がでてきません。

そこでjavaFxのモジュールパスを追加してjdepsしてみました。

>jdeps --module-path C:\Java\javafx-sdk-15.0.1\lib -s build\libs\testFatjar-1.0-all.jar
警告: 分割パッケージ: com.sun.glass.events .......
警告: 分割パッケージ: com.sun.glass.ui .......
.......
.......
警告: 分割パッケージ: javafx.util .......
警告: 分割パッケージ: javafx.util.converter .......
testFatjar-1.0-all.jar -> java.base
testFatjar-1.0-all.jar -> java.desktop
testFatjar-1.0-all.jar -> java.scripting
testFatjar-1.0-all.jar -> java.xml
testFatjar-1.0-all.jar -> jdk.jfr
testFatjar-1.0-all.jar -> jdk.unsupported

大量の警告: 分割パッケージが出た後に依存モジュールが表示されました。しかもjavaFxはでていません。
良く分かりません。ただ、javaFxの分はmodule-info.javaで分かるので、そちらを利用します。
また、jdepsは警告の出ない「javaFxのモジュールパス無し」の方法を使うことにしました。

Jlink でカスタム JRE を作る

jdepsの結果とmodule-info.javaのjavaFxから、JlinkコマンドでカスタムJRE(jre-15-min)を作ります。

> jlink --compress=2 
--module-path "c:\Java\jdk-15.0.1\jmods;c:\Java\javafx-jmods-15.0.1" 
--add-modules java.base,
			  java.desktop,
			  java.scripting,
			  jdk.jfr,
			  jdk.unsupported,
			  javafx.controls,
			  javafx.fxml 
--output jre-15-min

module-path の c:\Java\jdk-15.0.1\jmods は既定で JAVA_HOME から読み込まれるので下記のように省略できます。

> jlink --compress=2 
--module-path c:\Java\javafx-jmods-15.0.1 
--add-modules java.base,
			  java.desktop,
			  java.scripting,
			  jdk.jfr,
			  jdk.unsupported,
			  javafx.controls,
			  javafx.fxml 
--output jre-15-min

作られたカスタムランタイム(jre-15-min)でFatjarを実行してみました。

> jre-15-min\bin\java -jar build\libs\testFatjar-1.0-all.jar
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
.......
.......

立ち上がりました。ところが、QRコードを表示するためにボタンクリックをするとエラーがでます。
どうもエラーの中に encoder や charset という言葉がよくでてきています。
ネットでいろいろ検索すると jdepsでの依存取得はロケールまで考えてないというサイトを見つけました。
その中では、日時や通貨などのロケール情報や、デフォルト以外のキャラクタセットはjdepsでは自動で解決されない。 とありました。

日時や通貨などのロケール情報には   jdk.localedata
デフォルト以外のキャラクタセットには jdk.charsets
を --add-module で追加する必要がある。とのことでした。

そこで、jdk.charsets を追加して作り直しです。

> jlink --compress=2 
--module-path c:\Java\javafx-jmods-15.0.1 
--add-modules java.base,
			  java.desktop,
			  java.scripting,
			  jdk.jfr,
			  jdk.unsupported,
		追加→ jdk.charsets,
			  javafx.controls,
			  javafx.fxml 
--output jre-15-min

新しく出来上がったjre-15-minで実行すると、ボタンクリックで問題なくQRコード表示ができました。
jdepsに現れないものがあるとは、どうもスッキリしません。


IntelliJ.Gradle.JavaFX (4) exewrapで実行可能jarをexe化する