2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

The Badass Runtime Plugin+Gradle+JPackageで自己完結型Javaアプリケーションインストーラを作る&パスも通す

Last updated at Posted at 2022-06-25

はじめに

どーもnaotikiKtです。とあるコンソールアプリにJavaを同梱して配布したくなったのでその時のハマりポイントとかを備忘録的な感じで書いておきます。

本記事はKotlinユーザーの方向けです。(Javaの方でもほとんど同じです。)

JPackageて何?

JDK 14から含まれるようになったJavaを同梱した様々なプラットフォームのネイティブインストーラを作成できるツールです。
もとはjavafxpackager(JDK 7),javapackager(JDK 11)て名前だったらしいです。

環境

Windows,Linux両方のインストーラーを作りたいので両方の環境を用意する必要があります。

Windowsの環境
OS: Windows 11
JDK: Amazon Corretto Version 17.0.3 (JDK 14以上が必要)
IDE: InteliJ IDEA 2022.1.3
Ubuntu(WSL)の環境
WSL: WSL2 Ubuntu
JDK: OpenJDK 17(≧JDK 14)

macOS?ナニソレオイシイノ?

The Badass Runtime Pluginを導入

Docs

Github

build.gradle.ktsにこんな感じで追記してください

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内のファイルを変更していきます。
私の場合はプラットフォームごとに分けて入れています。
image.png
build.gradle.ktsにも追記します。

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はアンインストール時に実行されるシェルスクリプトです。
(更新時も実行されるのかな?あんま詳しくないからよく知りません)

postinst
#!bin/sh

ln -s /opt/{アプリ名}/{実行ファイル} /usr/bin/{実行ファイル名}
exit 0
postrm
#!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
でインストールできます。

おわり

日本語記事が少ない気がしたので書いてみました。
思ったより長くなりましたね・・・
間違いは指摘してくださると幸いです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?