はじめに
どーもnaotikiKtです。とあるコンソールアプリにJavaを同梱して配布したくなったのでその時のハマりポイントとかを備忘録的な感じで書いておきます。
本記事はKotlinユーザーの方向けです。(Javaの方でもほとんど同じです。)
JPackageて何?
JDK 14から含まれるようになったJavaを同梱した様々なプラットフォームのネイティブインストーラを作成できるツールです。
もとはjavafxpackager(JDK 7),javapackager(JDK 11)て名前だったらしいです。
環境
Windows,Linux両方のインストーラーを作りたいので両方の環境を用意する必要があります。
OS: Windows 11
JDK: Amazon Corretto Version 17.0.3 (JDK 14以上が必要)
IDE: InteliJ IDEA 2022.1.3
WSL: WSL2 Ubuntu
JDK: OpenJDK 17(≧JDK 14)
macOS?ナニソレオイシイノ?
The Badass Runtime Pluginを導入
Docs
Github
build.gradle.ktsにこんな感じで追記してください
plugins {
+ id("org.beryx.runtime") version "1.12.7"
}
+ runtime {
+ jpackage {
+ //この中に色々書きます
+ }
+ }
次はjpackageブロックの書き方を説明します
jpackageブロック
jpackageブロック以下で使えるものの中からよく使いそうなものを説明します。
mainClass
メインクラスを指定します。
Kotlinで
fun main(args: Array<String>) {
//処理
}
このように書いていたらクラスMainKt
が生成されるので、mainClass="MainKt"
と書きましょう。
imageName
/installerName
その名の通り、プログラムのファイル名を指定できます。
outputDir
出力先を変更できます。
skipInstaller
インストーラーなど要らん!わしはプログラムとJavaが同梱されたフォルダだけほしいんじゃ!って方向けのオプションです。
installerOptions
jpackageにわたす引数を設定できます
installerType
インストーラの形式(deb,rpm,exe,msiとか)を指定します。
resourceDir
インストーラを作成するときの設定ファイルなどをオーバーライドできます。
詳しくは後ほど
プラットフォームごとに処理を分ける
ビルド時のOSはorg.gradle.internal.os.OperatingSystem.current()
で取得できます。
使用例↓
jpackage {
val currentOs = org.gradle.internal.os.OperatingSystem.current()
when{
currentOs.isWindows->{
resourceDir=file("$rootDir/res/windows")
outputDir="jpackage/windows"
}
currentOs.isLinux->{
resourceDir=file("$rootDir/res/linux")
outputDir="jpackage/linux"
}
}
}
次はそれぞれのOSごとの詳しい設定をしてみましょー
Windows編
コンソールアプリを作っている方へ
脳死でもなんでもいいので
imageOptions.add( "--win-console")
をjpackageブロックに追記しましょう。
これがないとなんかエラー吐いてきます。
Linux(主にUbuntu)編
installerType
が自動でdebにならないので
installerType="deb"
しましょう
ビルド!
./gradlew jpackage
成功したら成功です。(某構文)
インストール時にパスを通す
Pathとか環境変数設定したくなりますよね!
私はなりました。設定しましょう。
共通部分
resourceDir
でファイルをオーバーライドする必要があるのでもとのファイルを取得しましょう。
runtime {
jpackage {
+ installerOptions.add("--verbose")
+ installerOptions.add("--temp")
+ installerOptions.add("HogeHoge")
}
}
--verbose
で詳細のログ取得
--temp HogeHoge
でHogeHogeディレクトリ内に設定ファイルを出力します。
オプションを追記したら./gradlew jpackage
しましょう。
HogeHoge/
になんか色々出力されましたね。
Windowsの場合はconfigディレクトリ,Linux(Ubuntu)はimages/DEBIAN/にオーバーライドできるファイルが入っています。
jpackageリソースのオーバーライド JPackage Docs
今回使うファイルは、
Windowsならmain.wxs
Linuxならpostinst
,postrm
です
適当なディレクトリ(res
とします)を作ってそれらのファイルを入れましょう。
res内のファイルを変更していきます。
私の場合はプラットフォームごとに分けて入れています。
build.gradle.ktsにも追記します。
jpackage {
when {
currentOs.isWindows -> {
+ resourceDir = file("$rootDir/res/windows")
imageOptions.add("--win-console")
outputDir = "jpackage/windows"
}
currentOs.isLinux -> {
+ resourceDir = file("$rootDir/res/linux")
installerType = "deb"
outputDir = "jpackage/linux"
}
}
}
これで準備おーけーです
Windows編
main.wxsはWiX Toolset用のファイルで、環境変数を変更する機能があります。
main.wxsに
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
<ComponentGroupRef Id="Shortcuts"/>
<ComponentGroupRef Id="Files"/>
<ComponentGroupRef Id="FileAssociations"/>
</Feature>
こんなのありますよね?(なかったら、、、えー、頑張ってください)
追記します
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
<ComponentGroupRef Id="Shortcuts"/>
<ComponentGroupRef Id="Files"/>
<ComponentGroupRef Id="FileAssociations"/>
+ <Component Id="pathEnvironmentVariable" Guid="{YOUR_GUID}" KeyPath="yes" Directory="TARGETDIR">
+ <Environment Id="UpdatePath" Name="Path" Value="[INSTALLDIR]" Action="set" System="yes" Part="last" Separator=";" />
+ </Component>
</Feature>
{YOUR_GUID}
にはこんなツールを使って生成したGUIDで置き換えましょう。
これで環境変数PATH
にインストールパスが追記されます。わーい
Environment
の説明
Name
を変更すればPath以外の環境変数も変えられます。
Value
は設定するパスですね。この場合はインストール先が自動で設定されます。
System
はyesにするとシステム環境変数に設定されます。
Part
で全体を変更するかどこに追記するかを設定できます。
Permanent
をyesにするとアンインストールしても残ります。
他にもあるので詳しくはこちら
Linux編
/usr/bin下にシンポジックリンクを作ることにしました。
他にいいやり方あったら教えて下さい。
先程resに入れた、
postinstはインストール時に実行されるシェルスクリプト
postrmはアンインストール時に実行されるシェルスクリプトです。
(更新時も実行されるのかな?あんま詳しくないからよく知りません)
#!bin/sh
ln -s /opt/{アプリ名}/{実行ファイル} /usr/bin/{実行ファイル名}
exit 0
#!bin/sh
rm /usr/bin/{実行ファイル名}
exit 0
{}
の部分は適宜置き換えてください。
{アプリ名}はデフォルトではsettings.gradleのrootProject.name
だと思います。
オプションが指定されていない場合のデフォルト JPackage Docs
postinstで/usr/binにシンポジックリンクを作成し、postrmで削除しています。
ビルドした.debファイルを
sudo apt install ./hoge.deb
or
dpkg -i ./hoge.deb
でインストールできます。
おわり
日本語記事が少ない気がしたので書いてみました。
思ったより長くなりましたね・・・
間違いは指摘してくださると幸いです。