LoginSignup
25

More than 3 years have passed since last update.

[OpenJDK11&JavaFX13]IntelliJ+gradleでjavaFXアプリをビルドし、軽量JREと合わせて配布可能なパッケージを作成する

Last updated at Posted at 2019-10-01

配布可能なJavaFXアプリを作成したかったのですが、試行錯誤したのでこちらにまとめます。

環境

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

※macOS Mojave(10.14.6)でも同様の手順で作成できました。

$ java --version
openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)

$ jlink --version
11.0.4

JDKの選定

最初はJavaFXを同梱しているAmazon CorrettoなどのJDKを使用しようと思っていました。
しかし、以下の記事を読んで、今回はOpenjdk-11を使用し、JavaFXはライブラリとして使用し、配布時に軽量JREを生成することにしました。
OpenJFX時代のJDK選び - もしくはOpenJFX時代のアプリケーション配布

手順

IntelliJでgradleプロジェクトを作成

IntelliJで、新規gradleプロジェクトを作成します。

Screenshot from 2019-10-01 16-05-10.png

build.gradleにjavafx用の設定を追加

OpenJFXの公式サイトに記載されていた以下のソースを参考に、build.gradleを作成します。
https://github.com/openjfx/samples/blob/master/IDE/IntelliJ/Modular/Gradle/hellofx/build.gradle

なお、IntelliJの設定でもともと設定で「Automattically import this project on changes in build script files」にチェックを入れていますので、よしなにモジュールはインポートされます。

build.gradle
plugins {
    id 'java'
    id "org.openjfx.javafxplugin" version "0.0.8" // 追加
}

group 'com.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

// 追加
javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

// 実行可能Jarを作成する際のMainクラスを指定
jar {
    manifest {
        attributes 'Main-Class': 'Main'
    }
}

テスト用のJavaFxクラスを作成

Main.java
import javafx.application.Application;

public class Main {
    public static void main(String... args){
        Application.launch(MyApplication.class);
    }
}
MyApplication.java
import javafx.application.Application;
import javafx.stage.Stage;

public class MyApplication extends Application {
    public MyApplication(){
        super();
    }

    @Override
    public void start(Stage primaryStage) throws Exception{
        primaryStage.setTitle("Hello");
        primaryStage.setWidth(300);
        primaryStage.setHeight(200);
        primaryStage.show();
    }
}

こちらを実行した結果、以下の画面が立ち上がります。
Screenshot from 2019-10-01 16-43-52.png

buildして、実行可能JARファイルを作成

コンソールにて、gradle buildを実行します。
特に問題がなければ、実行可能jarファイルが作成されるかと思います。
Screenshot from 2019-10-01 16-47-08.png

この状態で、jarファイルを実行してみると・・・
Screenshot from 2019-10-01 16-48-17.png

このように、javafx.application.Applicationクラスが無いよと怒られます。
これは、openjdk-11.0.4のjre内に、JavaFXモジュールが存在していないからですね。

軽量JREを作成する

では、jlinkを使って今回のjarファイルを動作させるための軽量jreを作成していきましょう!
今回は、以下の記事を参考にさせていただきました。
配布用の軽量 JRE の作り方

まず、以下ページのDownloadsより、jmodsをダウンロードします。
https://openjfx.io/
Screenshot from 2019-10-01 16-54-31.png

ダウンロードしたzipファイルを展開し、適当なパスに配置します。
(今回は、/usr/lib/jvm/javafx-13-openjfx/javafx-jmods-13に配置しています。)

なお、今回はLinux用jmodsをダウンロードしました。
※各実行環境のOSに合わせ、モジュールをダウンロードしましょう。

次に、jdeps ${jarファイルパス}コマンドにて、今回のjarファイルを実行するために必要なモジュールを調べます。
Screenshot from 2019-10-01 16-56-53.png

今回は、以下のモジュールを使えば良さそうです。
・java.lang -> java-base
・java.application -> javafx.base
・javafx.stage -> javafx.controls

※本当は、jdeps --list-deps ${jarファイルパス}とすると、どのモジュールを使えばよいかわかるようですが、何故かこのオプションが使用できず・・・。

必要なモジュールがわかったので、軽量jreを作成します。
以下のjlinkコマンドで、上記のモジュールを指定して作成できました。

$ jlink --compress=2 --module-path /usr/lib/jvm/java-11-openjdk-amd64/jmods:/usr/lib/jvm/javafx-13-openjfx/javafx-jmods-13 --add-modules java.base,javafx.base,javafx.controls --output jre

カレントパスにjreディレクトリが作成されました。
jre/bin/javaのバイナリも作成されています。

Screenshot from 2019-10-01 17-23-21.png

作成したJREを使用して、JARファイルを実行する。

では、最後に作成したjreを利用して、プログラムを実行してみましょう。

$ ./jre/bin/java -jar build/libs/javafx-sample-1.0-SNAPSHOT.jar 

Screenshot from 2019-10-01 17-30-28.png

無事に実行できました!

あとはJARファイルとjreをよしなにディレクトリにまとめ、実行用のシェルやbatファイルを作成するなり、appパッケージにまとめるなりすると完成です。
(以下は、フォルダにまとめ、シェルを作った例)

$ ls
javafx-sample-1.0-SNAPSHOT.jar  jre  start.sh

$ cat start.sh
#!/bin/sh
BASE=$(cd $(dirname $0); pwd)
$BASE/jre/bin/java -jar $BASE/javafx-sample-1.0-SNAPSHOT.jar

## sh start.shで実行可能

お疲れ様でした!

初めてjlinkやjdepsなどのコマンドを使い軽量JREを作成しましたが、使用者の環境(jdkなど)に依存しないで実行できるJavaFXアプリを作る際は、この方法が簡単かなと思います。
なお、今回のjreディレクトリのサイズは368.3MBなので、もっと色々できるようにすると重たくなってしまうのかな?

以上です。ありがとうございました!

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
25