jpackageを使ってJavaアプリケーションの配布用パッケージを作成する

Red Hat のソリューションアーキテクトの瀬戸です。

概要

OpenJDK 14からjpackageというインストーラーを作るためのツールが同梱されるようになりました。 もともとはJavaFXにあったjavapackagerがベースとなっているツールです。 Windows/Linux/Mac用のインストーラーを作成することができます。

もともとJava 8まではJava Web Start等でアプリケーションの配布を行っていましたが、セキュリティ上の理由によりオミットされてしまったのでそちらの代替となるアプリケーションの配布方法になります。

こちらを使用するとJavaで作られたアプリケーションだけでなく、OpenJDK(Javaの実行環境)も同時に配布できるパッケージを作成できます。 これだけでOpenJDKのインストールができ、アプリケーションが実行されるOpenJDKのバージョンも固定できるので、クライアントアプリケーションを作りたい場合は便利なツールです。

今回はこちらを使用して、Windows向けの配布パッケージ(msi)を作っていきます。

ちなみに、JEP 343: Packaging Tool で提案されて実装されました。 openjdk.org

ツールのインストール

OpenJDK

jpackageはOpenJDKに含まれるツールなのでOpenJDKをインストールします。 今回はRed HatもサポートしているEclipse Temurinを使用します。

adoptium.net

Eclipse Temurinの以下のリリースを使用しました。

openjdk 21 2023-09-19 LTS
OpenJDK Runtime Environment Temurin-21+35 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Temurin-21+35 (build 21+35-LTS, mixed mode, sharing)

jpackageはインストール先のbinの中に入っています。binの下にPATHが通っていることを確認してください。

WiX Toolset

WiX Toolset v3をインストールする必要があります。v4系もリリースされていますが、そちらでは動作しません。

wixtoolset.org

WiX Toolset v3のダウンロードはgithubから行うことができます。 wix311-binaries.zipをダウンロードしてPATHの通っている場所に解凍して置いておくのが簡単です。

github.com

WiXのインストールに失敗している場合はjpackageの実行時に次のようなメッセージが表示されます。

[14:24:55.174] WiXツール(light.exe、candle.exe)が見つかりません
[14:24:55.174] WiX 3.0以降をhttps://wixtoolset.orgからダウンロードし、PATHに追加します。
エラー: 無効またはサポートされていないタイプ: [msi]

今回使用するサンプル

今回使用するアプリケーションのサンプルは以下に保存してあります。入力しているパラメーターと実際のソースコードを比べたい場合は見てみてください。

github.com

実際に使用してみる

Javaアプリケーションはmaven等でビルドをして、jarファイルを作成しておきます。複数のjarを含めることもできます。 今回のサンプルの場合は、mvn packageでビルドをすることでjarファイルを作成できます。 jarの中には起動させるためのmainメソッドが含まれている必要があります。

jpackage -hで使用できるオプションの一覧が表示されます。日本語化もされているので、使う前に一度見てみるとよいでしょう。

jpackage -hの結果

今回はmsi形式を作ります。

msi形式を作る場合、デフォルト設定でprogram files配下にサイレントインストールされるパッケージが作成されます。それだと使いにくいのでいくつかのインストール時の設定を加えて実行します。

C:\>jpackage --type msi --win-menu --win-dir-chooser --win-shortcut --win-shortcut-prompt --input .\clientexample\target --name clientexample --main-class com.redhat.clientexample.App --main-jar clientexample.jar

それぞれのオプションの意味は次の通りです。

オプション 説明
type 作成する形式(今回はmsi)
win-menu Windowsメニューに登録する
win-dir-chooser インストール先を選択できるようにする
win-shortcut ショートカットを作成する
win-shortcut-prompt ショートカットを作成するかどうかプロンプトを表示する
input アプリケーションに含めるフォルダ
name アプリケーションの名前
main-class 起動するmainメソッドの含まれているクラス
main-jar 起動するjar

inputでパッケージ化するフォルダを指定している(=jar以外も含めることができる)というのがポイントでしょうか。 詳細についてはjpackage -hを参照してください。

実行すると、何事もなかったように終了し、msiパッケージが作成されます。

生成されたmsiファイル

msiを起動するとセットアップウィザードが起動します。普通のWindowsインストーラーですね。

インストーラー起動

インストール先を変更することができます。

インストール先の変更

ショートカットの作成を選択することができます。

ショートカットの作成

指定するとインストールを開始できます。

インストールの開始

スタートメニューにショートカットを追加するを選択しているので、ショートカットが作成されています。一般的なWindowsアプリケーションのインストールと変わりありません。

スタートメニュー

デスクトップにショートカットを作成することを選択しているので、デスクトップにショートカットが作成されています。こちらも一般的なWindowsアプリケーションのインストールと変わりありません。 リンク先はWindowsの実行ファイル(exe)になっています。jarへリンクが張られているわけではありません。

デスクトップ

実行すると普通に起動します。普通にとしか言えません。

アプリケーションの起動

インストールしたアプリケーションのフォルダを見ると、exeファイルが一つと、appとruntimeというフォルダを見つけることができます。 ショートカットからはこちらのexeにリンクが張られています。

インストール先のフォルダ

appの下にはinputで指定したフォルダの配下のファイルと、いくつかのメタデータが生成されて入っています。今回はmavenビルドの成果物をそのまま使用しているため余分なファイルが含まれています。 実際に配布する場合は配布用のフォルダ構成を別途用意してからインストーラーを作成することで配布物のサイズを抑えることができます。

app配下にはinputで指定したファイルが置かれている

runtimeの下にはOpenJDKから必要なもののみが配置されています。デフォルトでは開発ツール類は入ってきません。 OpenJDK由来のファイルについてはjlinkを使用して準備されます。配布ファイルのサイズを小さくしたい場合はjlinkにオプションを渡すことで実現できます。

runtimeの下にはOpenJDK由来のランタイムが置かれている

まとめ

かつてのJavaアプリケーションはランタイムとユーザーアプリケーションの配布タイミングが異なっていたため、複数のJavaバージョンを混在させることが難しく、ランタイムのバージョンアップ時に考慮する必要がありました。 現在ではアプリケーションと同時にランタイムを配布する方式もサポートされているため、管理がしやすくなっています。 Windows/Mac/Linuxで同じように動作するデスクトップアプリケーションが必要な場合は現在でも有効な選択肢の一つですので、ぜひお試しください。


追記:

知らなかった・・・・ learn.microsoft.com


続きを書きました。

rheb.hatenablog.com

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。