jlinkで他プラットフォームのJREを作成する(クロス・ターゲット)

以前の記事 JRE が単体で配布されなくなった理由 では Java アプリケーションに軽量化した JRE をバンドルする配布方式について紹介しました。

従来のシステムワイドに Java をインストールする方法では 一部のアプリケーションの都合で Java のバージョンを据え置かなければならない状況を生むことがありました。1 つのアプリケーションが新しいバージョンの Java で動作検証されていない たったそれだけの理由で古い Java が使われ続けるなんてこともあったのです。古いバージョンの Java がシステムに居座り続けていると 当然 悪循環に陥ります。

 すでに Java 5 がインストールされているから新規アプリも Java 5 で作ってね!

もうこれ一生抜け出せないパターンじゃないですか…。

そんな私に手を差し伸べてくれたのは jlink でした。Java 9 で登場した jlink によってアプリケーションごとに軽量化したカスタム ランタイム イメージ JRE を作成できるようになりました。システムワイドに Java をインストールするのではなく アプリケーションに JRE をバンドルする配布方式が推奨されるようになったのです。

この配布方式は システムにインストールされた Java のバージョンに束縛されなくなる アプリケーションごとに Java のバージョンを自由に選択できる というメリットをもたらしました。しかし 良い事ばかりではなかったのです。

 プラットフォームごとに JRE 作らないといけないのでは?

そうなんです。アプリケーションに JRE をバンドルするということは その配布物がプラットフォームに依存してしまうことを意味します。Windows 用の JRE をバンドルしたアプリケーション配布物は Linux では動きません。Linux で動かすためには Linux 用の JRE をバンドルしたアプリケーション配布物を用意しなければならないのです。

Windows/Linux/macOS に対応するだけでも 3 つのアプリケーション配布物が必要になります。そもそも 私は Mac を持ってないのですが macOS 用の JRE をバンドルしたアプリケーション配布物を作ることができるのでしょうか?

jlink はクロス ターゲットに対応しています

幸いなことに jlink は他のプラットフォーム向けのカスタム ランタイム イメージ JRE を作成することができます。Windows しか持っていなくても Linux macOS 用の JRE をバンドルしたアプリケーション配布物を作れるということです。

それでは 実際に Windows Linux 用の JRE をバンドルしたアプリケーションを作ってみましょう。macOS 用を作っても動作確認ができないので Linux 用を作って VirtualBox にインストールした Ubuntu で動作確認します

JDK をダウンロードする

jlink で他のプラットフォーム向けの JRE を作成する場合は 作業環境として動作する JDK とターゲット環境の JDK の両方が必要になります。

今回は Liberica JDK から JDK 11.0.4 Windows 64 ビット用と Linux 64 ビット用をダウンロードしました。ターゲット環境となる Linux 用はアーカイブの中からモジュールファイルを取り出すことが目的なので TAG.GZ 形式を選択します。

Liberica JDK
Liberica JDK は数多くのプラットフォームと Java バージョンを幅広くサポートしており 非常に網羅性の高い OpenJDK ディストリビューションです。これだけのプラットフォームと Java バージョンの組み合わせを提供しているディストリビューションは他にないでしょう。少しでも多くのエンドユーザーにリーチしたい Java アプリケーションの配布を意識している開発者さんにオススメのディストリビューションです。

ダウンロードした bellsoft-jdk11.0.4-windows-amd64.zip C:¥jdk-11.0.4 に展開します。これは作業環境として使います。すでに JDK をインストールしている場合は インストール済みの JDK を使っても構いません。

コマンドプロンプトを起動して C:¥jdk-11.0.4¥bin PATH を通します。java コマンドが使えることも確認しておきましょう。

コマンドプロンプト
C:¥>SET PATH=C:¥jdk-11.0.4¥bin;%PATH% C:¥>java --version openjdk 11.0.4-BellSoft 2019-07-16 OpenJDK Runtime Environment (build 11.0.4-BellSoft+10) OpenJDK 64-Bit Server VM (build 11.0.4-BellSoft+10, mixed mode)

サンプル アプリケーション

簡単なサンプル アプリケーションを用意しました。以下のリンクから fx-sample.zip をダウンロードして展開すると fx-sample.jar が入っています。

fx-sample.jar を適当なフォルダー C:¥temp にコピーして Windows 環境で実行できることを確認しておきましょう。

コマンドプロンプト
C:¥>java -jar C:¥temp¥fx-sample.jar

ウィンドウが表示されれば OK です。×ボタンを押して閉じます。

Linux 用の jmods をコピーする

ここからが本番です。

ダウンロードした Linux 用の JDK bellsoft-jdk11.0.4-linux-amd64.tar.gz を展開して jmods フォルダーを取り出します。必要なのは jmods フォルダーのみです。他のファイルは必要ありません。

取り出した jmods フォルダーを適当な場所にコピーします。私は Windows JDK フォルダー C:¥jdk-11.0.4 の中に jmods-linux-amd64 というフォルダー名にリネームしてコピーしました。

これで準備は完了です。サンプル アプリケーション fx-sample.jar を実行するための JRE を作成していきます。

Windows 用の JRE を作成する

まずは Windows 用の JRE 作成です。いつも通り --module-path jmods フォルダーを指定します。

コマンドプロンプト
C:¥>jlink --compress=2 --module-path "C:¥jdk-11.0.4¥jmods" --add-modules javafx.controls --output C:¥temp¥jre-11.0.4-windows-amd64

これで Windows 用の JRE C:¥temp¥jre-11.0.4-windows-amd64 に作成されました。

Linux 用の JRE を作成する

続いて Linux 用の JRE 作成です。違いは Linux JDK から取り出した jmods フォルダーのパス jmods-linux-amd64 にリネーム済み --module-path 引数に指定することだけです。

コマンドプロンプト
C:¥>jlink --compress=2 --module-path "C:¥jdk-11.0.4¥jmods-linux-amd64" --add-modules javafx.controls --output C:¥temp¥jre-11.0.4-linux-amd64

これで Linux 用の JRE C:¥temp¥jre-11.0.4-linux-amd64 に作成されました。あっけないほど簡単でしたね。

2 つの jre フォルダーが揃っています。ちなみに jre-11.0.4-windows-amd64 フォルダーのサイズは 59MB zip 圧縮すると 42MB jre-11.0.4-linux-amd64 フォルダーのサイズは 81MB gzip 圧縮すると 50MB でした。

Windows 環境で作成した Linux 用の JRE jre-11.0.4-linux-amd64 本当に動くんでしょうか? 気になりますね。試してみましょう。

サンプル アプリケーションを Linux で動かしてみる

動作確認用の Linux として VirtualBox Ubuntu 18.04 LTS をインストールしました。そして ~/work fx-sample.jar jre-11.0.4-linux-amd64 をコピーします。

サンプル アプリケーションを実行してみましょう。

あっさりと動きました。

Windows で作成した Linux 用の JRE の動作 問題なしです。

JRE の単体配布は本当に必要なくなったのでしょうか?

jlink はクロス ターゲットに対応しており JDK 環境が 1 つあれば 他プラットフォームのカスタム ランタイム イメージ JRE を作成できることが分かりました。Windows があれば Linux macOS Solaris Raspberry Pi 向けに JRE をバンドルしたアプリケーション配布物が作れます。もちろん 作業環境は Windows に限定されません

Java 11 以降 Oracle JDK Oracle OpenJDK では単体の JRE は配布されなくなりました。このことからも Oracle がカスタム ランタイム イメージ JRE をアプリケーションにバンドルする配布方法を強く推していることが窺えます。

しかし 他の OpenJDK ディストリビューションに目を向けてみると AdoptOpenJDK をはじめとして単体 JRE の配布を継続しているディストリビューターの存在に気が付きます。なぜ 他のディストリビューターは JRE の単体配布を継続しているのでしょうか?

私は クロス ターゲットで Linux 用のアプリケーション配布物を作ってみて感じました。

 …めんどくさいです

試しに Linux 用を作ってみただけでこれです。macOS だとか 32 ビット Windows だとか プラットフォーム固有のアプリケーション配布物を作っていったらキリがありません。そして 考えました。

  • 64 ビット Windows 用のアプリケーション配布物 JRE バンドル
  • その他プラットフォーム用のアプリケーション配布物 JRE なし

この 2 つだけ用意すればいいんじゃないかと。開発者さんによってはメインとなるターゲットが Linux だったり macOS だったりすることもあると思います。それでも考え方は同じです。あらゆるプラットフォーム向けに個別のアプリケーション配布物を用意するのは手間が掛かります。メインとなるターゲット プラットフォームに対しては カスタム ランタイム イメージ JRE をバンドルしたアプリケーション配布物を用意します。けれど 他のマイナープラットフォームに向けには JRE をバンドルしない .jar 直接配布で済ませてしまうのもアリではないかと思いました。マイナーとか言ってごめんなさい

jpackage
JEP 343 提案に沿って jpackage という新たなパッケージング ツールの開発も進められています。jpackage によってプラットフォーム固有のネイティブなインストーラーとネイティブなランチャーが作成できるようになります。しかし この jpackage はプラットフォーム固有のツールに依拠するため 実行環境と同じプラットフォームのパッケージしか作成することができません。Windows 用のインストーラーを作成するには Windows jpackage を実行する必要があるということです。これでは様々なプラットフォーム向けのアプリケーション配布パッケージを揃えるのは困難です。

きっと他にも様々な理由があります。理由はともかく 今後も JRE を含まない .jar 直接配布のアプリケーションは無くなることなく続いていくでしょう。

そのような .jar 直接配布アプリケーションを実行する場合 エンドユーザーさんには 別途 Java をインストールしてもらう必要があります。このようなケースで 開発者向けの JDK ではなくユーザー実行環境としての JRE が用意されていると助かるわけです。クリックぽちぽちで進むインストーラー形式になっていると簡単でいいですね。

JRE には単体配布される意味があります。

OpenJDK ディストリビューターさん 今後も JRE 単体配布の継続よろしくお願いします。

オススメの JRE は?

アプリケーションに JRE がバンドルされたパッケージがあるなら それを使うのが一番良いです。ここでは JRE バンドルが提供されていない .jar アプリケーションを動かすために JRE をインストールしなければならなくなったら何を選ぶか? という話をします。

JavaFX を使っていないアプリケーションであれば AdoptOpenJDK の配布している JRE がオススメかな。インストーラー形式もあります。しかし システムワイドにインストールできる JRE は実質的に 1 つだけなので AdoptOpenJDK JRE をインストールしてしまうと JavaFX アプリケーションを動かしたくなったときに困るかもしれません。

JavaFX を使っているアプリケーションを動かす場合はどれを勧めていいのか迷います。

Zulu Community JavaFX を同梱した JRE がある数少ないディストリビューションです。インストーラー形式の JRE が配布されていないのが残念。JDK にはインストーラー形式と圧縮アーカイブ形式の両方が揃っているのに なぜか JRE は圧縮アーカイブ形式のみ。JRE こそインストーラー形式が望まれていると思うのだけれど…。Zulu Community がインストーラー形式の JRE を配布するようになったら Zulu Community を勧めます。

Liberica JDK JDK としてはイチオシなのですが 残念ながら JRE は配布されていません。JRE の代わりに 巨大な JDK をインストールしてもらうというのもアリでしょうか? Liberica JDK はインストーラー形式もあるので サイズが大きいことに目をつぶれば 圧縮アーカイブ形式の Zulu Community JRE よりはエンドユーザーに勧めやすいです。Liberica JDK JRE を配布するようになったら 迷わず Liberica JDK を勧めます。

2019-12-02 追記
Liberica JDK 11.0.5 から JavaFX がバンドルされた JRE も配布されるようになりました。Windows 用は ZIP 形式だけでなく MSI インストーラー形式も用意されており エンドユーザー向けの Java 実行環境として最適です!
この記事を共有しませんか?