私はJava 8アプリケーションで、JavaFXを使用し、メインクラスが拡張されているjavafx.application.Applicationです。現在、 、私はそれをファットjarとして配信し、Oracleで正常に動作しますJava 8。
OpenJDK 11で実行できるようになりました。JavaFXを追加するために、org.openjfxからのアーティファクトをクラスパスに追加し、ファットjarに含めています。コマンドラインからjarを起動すると、
Error: JavaFX runtime components are missing, and are required to run this
application
この問題を回避する方法が2つありました。
回避策として1.を使用することもできますが、モジュール化されていないJavaFXアプリケーションの実行可能ファットjarをビルド/配信するための現在の方法(OpenJDK 11)は何なのでしょうか。誰か助けてもらえますか?
(モジュール化されていない)JavaFX 11エンドアプリケーションをパッケージ化/配布するためのいくつかのオプションがあります。それらのほとんどは公式のOpenJFX docs で説明されています。
このサンプル を参照として使用します。 Gradleも使用します。 Maven(異なるプラグイン)でも、ビルドツールなしでも同様のことができます(ただし、これはお勧めしません...)。ビルドツールは今日では必須です。
これはまだ有効なオプションですが、モジュール式の設計を壊し、すべてをまとめてバンドルするため、推奨されるオプションではありません。また、注意しない限り、クロスプラットフォームではありません。
このサンプルでは、次のようなbuild.gradleファイルがあります。
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
}
repositories {
mavenCentral()
}
dependencies {
}
javafx {
modules = [ 'javafx.controls' ]
}
mainClassName = 'hellofx.HelloFX'
jar {
manifest {
attributes 'Main-Class': 'hellofx.Launcher'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Launcher
クラスの使用に注意してください。 OPで言及または説明されているように here 、ファットjarを作成するには、Application
から拡張されていないランチャークラスが必要です。
./gradlew jar
を実行すると、JavaFXクラスとyour現在のプラットフォームのネイティブライブラリを含むファットjar(約8 MB)が生成されます。
Java -jar build/libs/hellofx.jar
は通常どおり実行できますが、同じプラットフォームでのみ実行できます。
OpenJFXドキュメントまたは here で説明されているように、クロスプラットフォームjarを作成できます。
この場合、3つのグラフィックjarを含めることができます。これらは、プラットフォームに依存するコードとライブラリを持つものです。ベース、コントロール、およびfxmlモジュールは、プラットフォームに依存しません。
dependencies {
compile "org.openjfx:javafx-graphics:11.0.1:win"
compile "org.openjfx:javafx-graphics:11.0.1:linux"
compile "org.openjfx:javafx-graphics:11.0.1:mac"
}
./gradlew jar
は、これら3つのプラットフォームに配布できるファットjar(19 MB)を生成します。
(メモメディアとWebには、プラットフォームに依存するコード/ネイティブライブラリもあります)。
したがって、これはJava 8で使用したときと同じように機能します。しかし、前に述べたように、モジュールの機能を壊し、最近のライブラリやアプリの配布方法に合わせていません。
これらのjarのユーザーがJREをインストールする必要があることを忘れないでください。
では、プロジェクトにカスタムイメージを配布する場合はどうでしょうか。これには、ネイティブJREとランチャーがすでに含まれています。
モジュール化されていないプロジェクトがある場合、それは機能しないと言うでしょう。そうだね。しかし、jpackageについて話す前に、ここで2つのオプションを調べてみましょう。
badass-runtime-plugin は、非モジュールプロジェクトからランタイムイメージを作成するGradleプラグインです。
このbuild.gradleの場合:
plugins {
id 'org.openjfx.javafxplugin' version '0.0.5'
id 'org.beryx.runtime' version '1.0.0'
id "com.github.johnrengelman.shadow" version "4.0.3"
}
repositories {
mavenCentral()
}
dependencies {
}
javafx {
modules = [ 'javafx.controls' ]
}
mainClassName = 'hellofx.Launcher'
runtime {
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
}
./gradlew runtime
を実行すると、ランチャーを含むランタイムが作成されるため、次のコマンドを実行できます。
cd build/image/hellofx/bin
./hellofx
これはシャドウプラグインに依存しており、Launcherクラスも必要です。
./gradlew runtimeZip
を実行すると、約32.5 MBのこのカスタムイメージのZipを取得できます。
このZipを同じプラットフォームの任意のユーザーに配布できますが、JREをインストールする必要はありません。
他のプラットフォーム用のイメージのビルドについては targetPlatform
を参照してください。
私たちは非モジュール式のプロジェクトがあり、それを変更することはできないと考え続けています...しかし、それを変更するとどうなりますか?
モジュラー化することは大きな変更ではありません:module-info.Java
記述子を追加し、必要なモジュールを含めますモジュール化されていないjar(自動名に基づく)。
同じサンプルに基づいて、記述子を追加します。
module hellofx {
requires javafx.controls;
exports hellofx;
}
そして今、私はコマンドラインでjlink
を使うか、それのためのプラグインを使うことができます。 badass-gradle-plugin は、前述の著者と同じ作者によるGradleプラグインであり、カスタムランタイムを作成できます。
このビルドファイルで:
plugins {
id 'org.openjfx.javafxplugin' version '0.0.5'
id 'org.beryx.jlink' version '2.3.0'
}
repositories {
mavenCentral()
}
dependencies {
}
javafx {
modules = [ 'javafx.controls' ]
}
mainClassName = 'hellofx/hellofx.HelloFX'
今すぐ実行できます:
./gradlew jlink
cd build/image/bin/hellofx
./hellofx
または./gradlew jlinkZip
は、JREがインストールされていない場合でも、同じプラットフォームのマシンで配布および実行できるzipバージョン(31 MB)です。
ご覧のとおり、シャドウプラグインやLauncherクラスは必要ありません。 question のように、他のプラットフォームをターゲットにしたり、モジュール以外の依存関係を含めたりすることもできます。
最後に、アプリケーションの配布に使用できる実行可能インストーラーを作成するための新しいツールがあります。
これまでのところGAのバージョンはまだありません(おそらくJava 13まで待たなければならないでしょう)が、現在Javaで使用するには2つのオプションがあります。 11または12:
Java/JavaFX 11では、Java 12のJPackagerでの最初の作業からのバックポートがあり、 here を見つけることができます。それを使用することについての素晴らしい記事 ここ とそれを使用するgradleプロジェクト ここ があります。
Java/JavaFX 12では、Java 13で使用できるjpackage
ツールの build 0バージョン がすでに存在します。
これはツールの非常に予備的な使用です:
plugins {
id 'org.openjfx.javafxplugin' version '0.0.5'
}
repositories {
mavenCentral()
}
dependencies {
}
javafx {
version = "12-ea+5"
modules = [ 'javafx.controls' ]
}
mainClassName = 'hellofx/hellofx.HelloFX'
def Java_home = '/Users/<user>/Downloads/jdk-12.jdk/Contents/Home'
def installer = 'build/installer'
def appName = 'HelloFXApp'
task copyDependencies(type: Copy) {
dependsOn 'build'
from configurations.runtime
into "${buildDir}/libs"
}
task jpackage(type: Exec) {
dependsOn 'clean'
dependsOn 'copyDependencies'
commandLine "${Java_home}/bin/jpackage", 'create-installer', "dmg",
'--output', "${installer}", "--name", "${appName}",
'--verbose', '--echo-mode', '--module-path', 'build/libs',
'--add-modules', "${moduleName}", '--input', 'builds/libraries',
'--class', "${mainClassName}", '--module', "${mainClassName}"
}
ここで./gradlew jpackage
を実行すると、dmg(65 MB)が生成されます。これを配布してインストールできます。
従来の太いjarを使用することもできますが、Java 11以降に移行する場合、すべてがモジュール化されているはずです。 IDEサポートを含む、新しい(間もなく)利用可能なツールとプラグインは、この移行中に役立ちます。
私はここで最も単純なユースケースを提示したことを知っています。より複雑な実際のケースを試す場合、いくつかの問題があるでしょう...しかし、古いソリューションを使い続けるのではなく、それらの問題の解決に取り組むべきです。