Quantcast
Channel: torutkのブログ
Viewing all articles
Browse latest Browse all 442

JavaFXアプリケーションのJDK 11対応(配布編)

$
0
0

はじめに

JDK 8でのJavaFXアプリケーションは、javapackagerコマンドを使ってアプリケーションとアプリケーションの実行に必要なJava実行環境をまとめて固めて配布することができました。固め方には、zipアーカイブの他、WindowsLinuxMacOSそれぞれのソフトウェアパッケージ形式(インストーラー)とすることも可能です。

しかし、JDK 11からはJavaFXが分離した際にjavapackagerコマンドも外されてしまいました。OpenJDKでは、javapackagerを代替する新しい機能を開発中*1ですが、早くてJDK 12からとなります。それまでの間、jlinkコマンドを使ってアプリケーションとアプリケーションの実行に必要なJava実行環境をまとめることとします。なお、jlinkはOS固有のパッケージ形式(インストーラー)を作成することはできません。

jlinkコマンドを使った実行イメージの作成

jlinkコマンドは、指定したモジュールが依存するモジュール群をJDKから抜きだして、実行イメージまとめるのに使います。

モジュール対応したJavaFXアプリケーションの実行イメージの作成

JavaFXアプリケーションが、モジュール対応している場合はjlinkコマンドで簡単に実行イメージを作成することができます。

ただし、モジュールパスでJavaFXライブラリのパスを指定するときは、JavaFXSDKを展開したディレクトリではなく、JavaFX jmodsを展開したディレクトリを指定します。

D:\work\EarthGadget> jlink --module-path "C:\Program Files\Java\JavaFX\javafx-jmods-11.0.1";dist ^
--add-modules com.torutk.gadget.earth ^
--output runtime ^
--launcher earthgadget=com.torutk.gadget.earth/com.torutk.gadget.earth.EarthGadgetApp
  • --module-pathでは、JDK標準以外のモジュールを収容するディレクトリを指定します。ここでは、JavaFX jmodsファイルのあるディレクトリ(C:\Program Files\Java\JavaFX\javafx-jmods-11.0.1)と、アプリケーションのモジュール化JARファイルのあるディレクトリ(カレントディレクトリ下のdist)を指定しています。
  • --add-modulesでは、アプリケーションのメインモジュール(com.torutk.gadget.earth)を指定しています。
  • --outputでは、実行イメージを生成するディレクトリを指定しています。
  • --launcherでは、実行イメージの中にアプリケーション起動用のコマンド(シェルスクリプト/バッチファイル)の名前と起動するモジュールおよびメインクラス名を指定しています。

実行イメージが展開されるディレクトリに、JavaFX関係のライブラリ(ネイティブライブラリのdllファイル、クラスライブラリのJARファイル等)も展開されます。

outputオプションで指定したruntimeディレクトリ下のbinディレクトリには、launcherオプションで指定した起動スクリプトファイル(earthgadget)/起動バッチファイル(earthgadget.bat)があるので、UNIX系OSなら前者を、Windows OSなら後者を実行するとJavaFXアプリケーションが立ち上がります。

jlinkコマンドのmodule-pathオプションで、JavaFXSDKのlibディレクトリを指定すると、実行イメージの中にネイティブライブラリが含まれないので実行時にエラーとなってしまいます。jlinkコマンドでJavaFXを指定する場合は、JavaFXのjmodsを指定します。

モジュール対応していないJavaFXアプリケーションの実行イメージ作成(現状)

JavaFXアプリケーションがモジュール対応していない場合は、JavaFXアプリケーションが必要とするモジュールをjdepsコマンドでリストアップしてからjlinkコマンドでリストアップされたモジュールをそれぞれ指定します。

ただし現時点ではJDKのモジュールから必要なものを抜粋した実行イメージを生成することができますが、実行イメージにJavaFXライブラリとアプリケーションを含めることはできませんでした。

jdepsでアプリケーションの実行に必要なモジュールを調べる

まず、アプリケーションJARファイル(非モジュール対応)をjdepsで解析します。

D:\work\EarthGadget> jdeps --print-module-deps dist\EarthGadget.jar
java.base,java.prefs

D:\work\EarthGadget>
  • --print-module-deps は、jlinkコマンドのオプションで指定するモジュールリスト形式で出力するオプションです。今回はjdepsコマンドで解析した結果をjlinkで指定するのでこのオプションを指定しました。

アプリケーションが依存するJDKのモジュールのみ表示されます。JavaFXのモジュールはリストされません。また、JavaFXライブラリが必要とするJDKのモジュールもリストされていません。

そこで、JavaFXライブラリを解析対象に追加します。

D:\work\EarthGadget> jdeps --print-module-deps ^
 --module-path "C:\Program Files\Java\JavaFX\javafx-sdk-11.0.1\lib" ^
 --add-modules javafx.controls ^
 dist\EarthGadget.jar
Exception in thread "main" java.lang.NullPointerException
        at jdk.jdeps/com.sun.tools.jdeps.ModuleGraphBuilder.requiresTransitive(ModuleGraphBuilder.java:124)

うーん、ヌルポが出てしまいました。原因はよく分かりませんが、--print-module-deps を--list-depsに置き換えると回避できました。

D:\work\EarthGadget> jdeps --list-deps ^
 --module-path "C:\Program Files\Java\JavaFX\javafx-sdk-11.0.1\lib" ^
 --add-modules javafx.controls ^
 dist\EarthGadget.jar
   JDK removed internal API/com.sun.media.jfxmediaimpl.platform.ios
   JDK removed internal API/com.sun.media.jfxmediaimpl.platform.osx
   java.base
   java.datatransfer
   java.desktop/java.awt.dnd.peer
   java.desktop/sun.awt
   java.desktop/sun.awt.dnd
   java.desktop/sun.swing
   java.prefs
   java.scripting
   java.xml
   jdk.jsobject
   jdk.unsupported
   jdk.unsupported.desktop
   jdk.xml.dom

ちなみにリストされるモジュールは、JDKのモジュールのみでした。JavaFXライブラリのモジュールも表示されるのを期待していましたが、このオプション指定では出ませんでした。

jlinkでアプリケーションの実行に必要なJDKのイメージを作成する

先のjdepsコマンドで、このJavaFXアプリケーション実行に必要なJDKモジュールを抜粋して実行イメージを作成します。

D:\work\EarthGadget> jlink --add-modules java.base,java.datatransfer,java.desktop,java.prefs,java.scripting,java.xml,jdk.jsobject,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom --output runtime

生成された runtime ディレクトリの容量は約70MBとなりました。
ただし、JavaFXライブラリとアプリケーションはこのruntimeには含まれません。

jlinkで作成したJDKの実行イメージを使ってアプリケーションを実行する
D:\work\EarthGadget> runtime\bin\java --module-path "C:\Program Files\Java\JavaFX\javafx-sdk-11.0.1\lib" --add-modules javafx.controls -jar dist\EarthGadget.jar

まとめ

  • モジュール対応したJavaFXアプリケーションは、jlinkコマンドで実行に必要なJDK、ライブラリ(Javaクラスライブラリ、ネイティブライブラリ)、アプリケーションをまとめたアプリケーション実行イメージを生成できる。
  • モジュールに対応していないJavaFXアプリケーションは、jdepsコマンドで実行に必要なJDKのモジュールを解析し、続いてjlinkコマンドで必要なモジュールを抜粋し実行イメージを生成する。ただし、JDK以外のライブラリ、アプリケーションは実行イメージには取り込まれない。

*1:JEP 343: Packaging Tool


Viewing all articles
Browse latest Browse all 442

Trending Articles