JavaFX アプリケーションの配布

前回作成した JavaFX11 アプリケーション sampleFX11 を zip ファイルで配布することを考える。

以前(多分、Java 8 まで)は、アプリケーションを実行可能な jar ファイルにし、それを配布する。利用するユーザーは JRE(Java Runtime Environment)を自分のパソコンにインストールし(簡単にできた)、jar ファイルをダブルクリックすれば、簡単に実行できた。今(例えば、Java 11 で)は、JDK(Java Development Kit)をインストールするにも、少し、手間がかかる。Java 11 では JRE がなくなったようである。また、JavaFX が Java に含まれなくなったようで、JavaFX も自分でインストールする必要がある。実行可能な jar ファイルの形で JavaFX アプリケーションを配布されたユーザーが、それを実行するためにだけ、Java 11 と JavaFX 11 をインストールするのは現実的ではない。しかし、このJavaFX アプリケーション用の(小さな)JRE を作成でき、それも含めて配布すれば、ユーザーが簡単に実行できるようになった。

配布用の小さな JRE の作成と、exewrap を利用して jar ファイルから exe ファイルを作ること等に関して、「アプリケーション配布用に小さなJREを作る」と「OpenJDKでJavaアプリ配布パッケージを作る」を参照させていただきました。

準備として、exewrap をダウンロードし、(exewrap.exe を)適切なディレクトリにおき、(exewrap を容易に利用するために)このディレクトリを PATH に追加する。

大体の流れは次の通りである。

  1. 実行可能 jar ファイルを作成する。
  2. jdeps を実行し、必要なモジュールを求める。
  3. jlink を実行し、アプリケーションの実行に必要な小さな JRE を作成する。
  4. exewrap を実行し、jar ファイルから exe ファイルを生成する。
  5. 必要なディレクトリとファイルを zip ファイルに圧縮する。

以上のことを、前回作成した sampleFX11 を具体例として、実際に行う。

実行可能 jar ファイルの作成は、Eclipse で行う。Eclipse を起動し、(必要ならば)プロジェクト sampleFX11 を開く。メニューから、File > Export… を選ぶ。現れたダイアログボックスで Runnable JAR file を選び、Next > ボタンを押す。

File > Export…

次のダイアログボックスにおいて、Launch configulation: では、右にある∨を押し、このプロジェクトの main 関数があるクラスを探して選ぶ。Export destination: では、実行可能 jar ファイルを入れるディレクトリとファイル名を指定する。ここでは、このプロジェクトのディレクトリ sampleFX11 の下に dist というディレクトリを作成し、そこに入れるファイル名を sampleFX11.jar とした。残りの設定ものように行い、Finish ボタンを押す。

File > Export… 最後の設定

実行可能 jar ファイル sampleFX11.jar と sampleFX11_lib ディレクトリが作成された

実行可能 jar ファイルとライブラリディレクトリ

以後は主にコマンドプロンプトでの作業ある。スタートボタンから Windows システム ツール > コマンドプロンプト を選び、カレントディレクトリを先ほど作成した、sampleFX11\dist にする。コマンドプロンプトで

jdeps --module-path sampleFX11_lib --list-deps sampleFX11.jar

と jdeps を実行する。これは、sampleFX11.jar を実行するための JRE を作成する際にどのモジュールが必要かを調べている。その結果、

   java.base
   javafx.base
   javafx.controls
   javafx.fxml
   javafx.graphics

と表示され、この5つのモジュールが必要であることが分かる。次に、jlink を利用して、これらのモジュールが含まれる JRE を作成する。コマンドプロンプトで

jlink --compress=2 --module-path "absolute-path-to-OpenJDK11\jmods;absolute-path-to-JavaFXjmods" --add-modules java.base,javafx.base,javafx.controls,javafx.fxml,javafx.graphics --output jre-11.0.2

と入力する。ただし、オプション –module-path にある absolute-path-to-OpenJDK11 と absolute-path-to-JavaFXjmods は最初にすることに出てきたもので、OpenJDK11 と JavaFX jmods を実際にインストールしたディレクトリに置き換える。これらをダブルクォートで括ったのは、パスに空白が含まれていると想定しているからである。また、–add-mudules オプションには、jdeps で分かったモジュールをコンマで区切って(空白は入れずに)並べる。–output オプションで作成される JRE を出力するディレクトリ名を指定する。ここでは、jre-11.0.2 とした。後で exewrap を利用するので、jre で始まる文字列が良く、ここでは、JDK のバージョンも付加した。これで、sampleFX11 用の JRE を含む jre-11.0.2 ディレクトリが作成された

jre-11.0.2 ディレクトリ

この段階で、jre-11.0.2 には sampleFX11.jar を実行するために必要な JRE が含まれていることが次のようにして確かめられる。コマンドプロンプトにおいて、カレントディレクトリは sampleFX11\dist であり、

java -jar sampleFX11.jar

と入力すると、以下のエラーになる。

エラー: JavaFXランタイム・コンポーネントが不足しており、このアプリケーションの実行に必要です

これは最初にすることでインストールした AdoptOpenJDK11 の java.exe を起動し(理由:PATH に入っているため)、AdoptOpenJDK11 の JDK を利用しているためである。jre-11.0.2 にある JRE を利用するために、jre-11.0.2\bin にある java.exe で sampleFX11.jar を起動してみる。すなわち、コマンドプロンプトで

jre-11.0.2\bin\java -jar sampleFX11.jar

と入力すると、正常に実行される。

次に、exewrap を利用して、sampleFX11.jar から sampleFX11.exe を生成する。コマンドプロンプトで

exewrap -g sampleFX11.jar

と入力すると、sampleFX11.exe が生成される。ここで、-g オプションで、ウィンドウ・アプリケーションを作成するように指定している。

sampleFX11.exe

生成された sampleFX11.exe をダブルクリックして実行すると、背景色が変わらない。sampleFX11.log に次のようなエラーが出る。

??? ??, ???? ??:??:?? ?? com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "***/dist/sampleFX11.exe!/application/application.css" not found.

回避策として、dist ディレクトリ以下に、src ディレクトリにある application\application.css をコピーする。これで、sampleFX11.exe を実行してもエラーが出ず、背景色が描画される。

application ディレクトリ

最後に、application と jre-11.0.2 ディレクトリと sampleFX11.exe を(sampleFX11_lib と sampleFX11.jar は不要である)、例えば、sampleFX11.zip として圧縮する。この zip ファイルを配布すればよい。

sampleFX11.zip

ユーザーが解凍後、 sampleFX11.exe を実行すればよい。