Javaのスタンドアロンアプリケーション配布をする場合、JREを同梱しておくと環境設定が要らなくなるのですが、そのためには各プラットフォーム向けのJREをアプリケーションに同梱する必要があります。
フルサイズのJREを同梱してもいいのですが、Java9以降はモジュールがサポートされているので、せっかくなら必要な分だけを入れたJREを作る方が望ましいわけですが、その場合には各プラットフォーム向けのJDKに入っているjmods以下のファイルが必要になります。
セットアップのために手動でJDKをダウンロードするのは意外と手間なので、build.gradleに以下のようなスクリプトを追加してみました。
plugins {
id "de.undercouch.download" version "4.0.4"
}
task prepareJDK{
downloadAndExtractJDK("jdk/win",'http://download.bell-sw.com/java/11.0.6+10/bellsoft-jdk11.0.6+10-windows-amd64-full.zip')
downloadAndExtractJDK("jdk/mac",'http://download.bell-sw.com/java/11.0.6+10/bellsoft-jdk11.0.6+10-macos-amd64-full.zip')
}
void downloadAndExtractJDK(jdkDir,url){
def zipFile = "${jdkDir}/jdk.zip"
if(file(zipFile).exists()==false){
download {
src url
dest zipFile
}
}
if(file("${jdkDir}/LICENSE").exists()==false){
copy{
from( zipTree(zipFile) ){
include "**"
eachFile { fcd ->
fcd.relativePath = new RelativePath(true, fcd.relativePath.segments.drop(1))
}
includeEmptyDirs = false
}
into jdkDir
}
}
}
task buildJRE(type: Exec,dependsOn:prepareJDK) {
commandLine './buildJRE.sh'
}
これを
gradle buildJRE
とすると、JDKがダウンロードされて、各プラットフォーム用のJREがbin/jreに生成されます。
prepareJDKのタスクで、Win/MacのLiberica JDK11をダウンロードして展開します。
タスク自体は単純なものですが、zip展開の際にRelativePathを使って、1階層ファイルパスを引きあげています。
普通にJDKのzipを展開すると、"jdk/win/jdk-11.0.6"という形でJDKのバージョンが入ったフォルダが作られてしまうのですが、JREを作る際にバージョンが入るとちょっと使いにくいかったため、フォルダ内のファイルを1階層引きあげています。
またJREを生成するシェル(buildJRE.sh)は、jlinkを呼び出すシェルになっています。
# !/usr/bin/env sh
MODULES="java.base,java.desktop,javafx.controls"
for PLATFORM in win mac
do
OUTPUT_DIR=build/jre/$PLATFORM
JMODS_DIR=jdk/$PLATFORM/jmods
if [ -d $OUTPUT_DIR ]; then
echo "JRE for $PLATFORM exits in $OUTPUT_DIR"
else
echo "creating JRE for $PLATFORM in $OUTPUT_DIR"
jlink --compress=2 --module-path $JMODS_DIR --add-modules $MODULES --output $OUTPUT_DIR
fi
done
MODULESのところに、利用するモジュールをならべて書いておきます。Librica JDKはJavaFX同梱なので、JavaFXアプリには大変便利です。
開発が本格的にOpenJDKに移行し、各種JDKがダウンロードでき、必要な分のモジュールだけが作れるようになったのは大変喜ばしいことですね。