JavaFX & 自己完結型パッケージでのツール作成（配布編）


## このページについて
プロジェクトでツールが欲しいとなると、SI界隈ではまだまだExcelマクロが出張ってきますが、
得てして重いし保守性に難があるし、何か他にないかなと。
Javaのクライアントアプリなんかどうかと試しまして、その手順のまとめとなります。
※本ページでは作成したアプリの配布を扱います。[JavaFX実装編はこちら](https://qiita.com/ketman55/items/dc5d87c37e975a847e1a)。

---
## 自己完結型パッケージとは？
Javaのクライアントアプリのネックとして、起動する端末にJavaの実行環境を求める点があります。
すると、端末毎にバージョン差異で動いたり動かなかったりする。これでは流行らない。
そこで、配布用アプリケーションの中にJREも仕込んでおいて、アプリはこれを参照する様にします。
これで、端末側の環境に依らずにアプリを実行させることが出来ます。これなら流行る。

---
## 実行環境
|環境|サービス/バージョン|
|:--|:--|
|実行環境|Windows10|
|開発環境|eclipse 4.11.0|
|アプリケーション|JavaFXアプリケーション on Java11|

---
## 手順１．アプリケーションをjarにエクスポートする
今回はeclipseのGUIからエクスポートすることとします。
プロジェクト右クリック⇒エクスポートを選択

実行可能jarを選択し、次のファイル仕様の設定へ進みます。
完了を押下すると、実行可能jarと依存関係jarの入ったlibフォルダが出力されます。

 * 起動構成はこのパッケージのメインクラスを指定
    * eclipseで実行済みであればドロップダウンに居るはず
 * エクスポート先は適当に決める
 * ライブラリ処理は「生成されるJARの隣のサブフォルダーに必須ライブラリーをコピー」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/650ad68b-2f23-34e4-3fd2-ce470ec4c150.png)

実行可能jarと外部ライブラリ入りのフォルダが作成されました。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/90dc9495-892f-76e6-d377-4fde75b3abee.png)

---
## 手順２．アプリ用JREを作成する
次に、手順1で作成した実行可能jarが参照するJREを準備します。
eclipseで使っているJREをそのままコピーしてきても動作はしますが、
配布用ということで、なるべく必要最小限のサイズに収めたいことがモチベーションです。

---
先ずは、何を詰め込む必要があるかを確認します。
作成したモジュールの依存関係を確認すれば良く、
（JDK 8以降から追加された）jdepsコマンドによって確認できます。
※端末にJDKをインストールするか、eclipseのターミナルからでも実行できます。お好みで。

```
jdeps --module-path "※アプリケーション作成に使用したJREのパスを記載※\pleiades\java\11.0.2\lib" -s ※作成したjar※.jar
```

---
今回はJavaFXアプリケーションを作成したため、以下の様になりました。

```
LDAtool.jar -> java.base
LDAtool.jar -> javafx.base
LDAtool.jar -> javafx.controls
LDAtool.jar -> javafx.fxml
LDAtool.jar -> javafx.graphics
LDAtool.jar -> 見つかりません
javafx.base -> java.base
javafx.base -> java.desktop
javafx.controls -> java.base
javafx.controls -> javafx.base
javafx.controls -> javafx.graphics
javafx.fxml -> java.base
…（以下省略）
```

---
JRE化に当たってはjarと直接の依存関係にある部分のみを意識します。
今回は以下が該当します。

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

※javafx.graphicsはjavafx.controlsに依存している様で、実際はgraphicsは不要になります
※「見つかりません」は、外部jarとして取り込んだkuromoji君です。彼は手順１でlibへコピー済みですので、ここでは無視します。

---
以下の様に、jlinkコマンドにこれらのモジュールを与えて実行。
これで、jre-minという配布アプリケーション専用のJREが出来ました。

```
jlink --compress=2 --module-path "※アプリケーション作成に使用したJREのパスを記載※\pleiades\java\11.0.2\jmods" --add-modules java.base,javafx.base,javafx.controls,javafx.fxml --output jre-min
```

---
## 手順３．配布用のjarをexe化する

最後に、jarをexe形式にラッピングして、どの環境でもダブルクリック等で起動してくれる様にしましょう。
今回は、Launch4jというラッピングツールを用いて実施しました。

[こちら](http://launch4j.sourceforge.net/)からダウンロード/インストール。
以下を設定の上、歯車のアイコンを押下すると実行されます。

---
|設定事項|設定内容|
|:--|:--|
|Outputfile|exeファイルの出力先を指定（今回は配布したいので、JRE(jre-minフォルダ)と同じ階層を指定|
|jar|手順１で作成したjarファイルを指定|
|Bundle JRE Pass|手順２で作成したJREを指定（保管先に依存しない様に、exeの相対パスで指定）|
|Min JRE version|必須項目の様なので、JREのバージョンを記載する|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/5c6f514a-6826-9af6-96d7-4eed88227e28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/1c8fd270-96be-88ab-a2d0-d7c6a5f040ec.png)

---
exeファイルが生成されました。実行してみましょう。
アプリケーションが起動すれば成功です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/e8ea803a-ac24-e0f1-f52b-4ea3911bb9c1.png)

---
以上より作成したexeやjreの入ったフォルダを、zipで固めるなどして配布するイメージです。
※[ソース等と共にGitに置いてあります（export.zip）](https://github.com/ketman55/JavaFxSample/blob/master/export.zip)

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/38e2cba9-b7c4-f222-55f4-ce51d2993468.png)

---
## 参考資料

 * [アプリケーション配布用に小さなJREを作る](https://blogs.osdn.jp/2018/03/26/jre-minimize.html)
 * [初めてJavaを触った人間がEclipseでJavaFXのGUIアプリを起動するまで
](https://ateitexe.com/first-develop-javafx-application/)
 * [非モジュールJavaFXのアプリをJlinkで配布可能パッケージにする](https://skrb.hatenablog.com/entry/2018/12/24/142234)
 * [JDK、Oracle JDK、OpenJDK、Java SEってなに？](https://qiita.com/nowokay/items/c1de127354cd1b0ddc5e)