3
3

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.

gradleでjlinkを使う

Last updated at Posted at 2020-09-20

はじめに

jlinkを使うとアプリ専用のJREができて、配布に便利。
というわけでgradleで使う方法を調べてみた。

プロジェクトの準備

とりあえず普通に

gradle init --type=java-application

で作る。

build.gradleの書き換え

最低限必要なのは、pluginsの項目に以下の行を追加すること。

id 'org.beryx.jlink' version '2.25.0'

これで、gradle jlink が使えるようになる。

また、デフォルトで入っている dependencies は消しておくと警告が消える。(数字で終わるモジュール名がいけないらしい)

その他、JDKのバージョンによっては、

The module name specified in 'application.mainModule' (null) has not the expected value

という警告が出る。これは、applicationの項目に

mainModule = 'module名'

を書いておくと消える。(module名は module-info.java で指定したもの)

jlink の項目を作って、optionを設定することも可能。例えば以下のように書ける。
ちなみにMicrosoft buildのOpenJDK 17.0.5 では --strip-debug がエラーになった。とりあえず消せばビルドできる。

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}

targetPlatformで複数のプラットフォーム用アプリを作ることもできる。この場合、各プラットフォーム用のJDKを用意しておく。

jlink {
    targetPlatform("mac") {
        jdkHome = "/usr/java/jdk-mac/Contents/Home"
    }
    targetPlatform("linux-x64") {
        jdkHome = "/usr/java/jdk"
    }
    targetPlatform("windows-x64") {
        jdkHome = "/usr/java/jdk-win"
    }
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}

ビルド

gradle build

では、jlinkを使わずにjarができる。jlinkする場合は、以下のようにする。

gradle jlink

これで build ディレクトリの下に image ができ、その下のディレクトリがあれば実行できるようになっている。
targetPlatformを指定している場合は、app-<ターゲットプラットフォーム名> のディレクトリができ、その下に置かれる。

アプリ実行のためには、bin ディレクトリに実行スクリプト(app)があるので、それを実行すれば良い。(Windows用の場合はapp.bat)

アプリの配布は bin, conf, legal, libの各ディレクトリ(要はimageディレクトリ)をまとめて配布すればOK。
そのままコピーして、appを実行すれば起動できる。

リソース

gradle init で準備したプロジェクトには app/source/main/resources ディレクトリがあるはず。ここにファイルを置いておくと、jlink で出来上がる modules の中にresourcesディレクトリ内のファイルが取り込まれる。
modulesにちゃんと入っているかは、jimage で確認可能。

jimage list app/build/image/lib/modules

とすると入っているファイル一覧が表示される。

このファイルは普通にgetResourceできる。
例えばresourcesにtest.pngを置いて、以下のようにすれば読み込める。

URL imgurl = App.class.getClassLoader().getResource("test.png");
Image img = Toolkit.getDefaultToolkit().getImage(imgurl);

ライブラリの利用

外部のライブラリも使用できる。例として Apache Derby を使ってみる。(module化されていて楽だったので)
まずは build.gradle の dependencies に指定する。これは jlink 関係ない部分。

dependencies {
        implementation group: 'org.apache.derby', name: 'derby', version: '10.16.1.1'
}

次に module-info.java に指定する。
module名が org.apache.derby ではないので注意。

module derbyjlink
{
        exports derbyjlink;
        requires java.base;
        requires java.sql;
        requires transitive org.apache.derby.engine;
}

この org.apache.derby.engine は jdeps を使って調べた。
module-info.java に derby の行を書かずに jlink build すると、app/build/distributions に配布ファイルができる。
その中に derby-10.16.1.1.jar が含まれるので、これを jdeps で調べる。

jdeps derby-10.16.1.1.jar
Exception in thread "main" java.lang.module.FindException: Module org.apache.derby.commons not found, required by org.apache.derby.engine
	at java.base/java.lang.module.Resolver.findFail(Resolver.java:893)
	at java.base/java.lang.module.Resolver.resolve(Resolver.java:192)
	at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
	at java.base/java.lang.module.Configuration.resolve(Configuration.java:421)
	at java.base/java.lang.module.Configuration.resolve(Configuration.java:255)
	at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
	at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:604)
	at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:558)
	at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:534)
	at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)

このようにエラーになるが、org.apache.derby.engine の module が org.apache.derby.commons を要求していることがわかる。
というわけで、requires transitive で org.apache.derby.engine を指定すると org.apache.derby.commons もリンクしてくれる。

module化されていないライブラリも同じ方法で行けるらしいが未確認。module-info.javaにライブラリのパッケージ名を書けば良いらしい。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?