[OpenJDK11&JavaFX13]IntelliJ+gradle로 javaFX 앱을 빌드하고, 경량 JRE와 함께 배포 가능한 패키지를 작성한다

배포 가능한 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 프로젝트를 만듭니다.



build.gradle에 javafx에 대한 설정 추가



OpenJFX 공식 사이트 에 기재되어 있는 이하의 소스를 참고로, build.gradle 를 작성합니다.
htps : // 기주 b. 코 m/오펜 jfx/사 mpぇs/bぉb/마s테 r/이데/인테페 J/모즈ぁr/G등 dぇ/헤에 fx/부이 ld. g 등 dぇ

또한 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();
    }
}

여기를 실행하면 다음 화면이 시작됩니다.


build하여 실행 가능한 JAR 파일을 만듭니다.



콘솔에서 gradle build를 실행합니다.
특별히 문제가 없다면 실행 가능한 jar 파일이 만들어질 것이라고 생각합니다.


이 상태에서 jar 파일을 실행해 보면 ...


이런 식으로 javafx.application.Application 클래스가 없으면 화가납니다.
이것은 openjdk-11.0.4의 jre 내에 JavaFX 모듈이 존재하지 않기 때문입니다.

경량 JRE 만들기



그럼, jlink를 사용해 이번 jar 파일을 동작시키기 위한 경량 jre를 작성해 갑시다!
이번은, 이하의 기사를 참고로 했습니다.
배포 용 경량 JRE를 만드는 방법

먼저 아래 페이지의 Downloads에서 jmods를 다운로드합니다.
htps : // 오펜 jfx. 이오/


다운로드한 zip 파일을 확장하고 적절한 경로에 배치합니다.
(이번에는 /usr/lib/jvm/javafx-13-openjfx/javafx-jmods-13 에 배치하고 있습니다.)

덧붙여 이번은 Linux용 jmods를 다운로드했습니다.
※ 각 실행 환경의 OS에 맞추어 모듈을 다운로드합시다.

그런 다음 jdeps ${jarファイルパス} 명령을 사용하여 이 jar 파일을 실행하는 데 필요한 모듈을 확인합니다.


이번에는 다음 모듈을 사용하면 좋을 것 같습니다.
· 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 의 바이너리도 작성되고 있습니다.



작성한 JRE를 사용해, JAR 파일을 실행한다.



그럼, 마지막으로 작성한 jre를 이용해, 프로그램을 실행해 봅시다.
$ ./jre/bin/java -jar build/libs/javafx-sample-1.0-SNAPSHOT.jar 



무사히 실행할 수 있었습니다!

그리고는 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이므로, 좀더 다양한 할 수 있도록(듯이) 하면 무겁게 되어 버리는 것일까?

이상입니다. 고마워요!

좋은 웹페이지 즐겨찾기