以下是打包/分发(非模块化)JavaFX11终端应用程序的几个选项。其中大多数都在官方OpenJFX中进行了解释
docs
.
我会用
this sample
作为参考。我还将使用Gradle。Maven(不同的插件)也可以做类似的事情,甚至不需要构建工具(但不建议这样做…)。构建工具现在是必须的。
肥罐
这仍然是一个有效的选项,但不是首选选项,因为它打破了模块化设计,将所有东西捆绑在一起,并且除非您注意到这一点,否则它不是跨平台的。
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
Application
现在需要创建一个胖罐子。
./gradlew jar
生成一个胖jar(~8MB),其中包括JavaFX类和
你的
当前平台。
你可以跑
java -jar build/libs/hellofx.jar
和往常一样,但只在同一个平台上。
如OpenJFX文档或
here
,您仍然可以创建一个跨平台jar。
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(19MB),可以分发到这三个平台。
(注意,媒体和Web也有平台相关的代码/本机库)。
因此,它在Java8上的工作方式与以前一样。但正如我之前所说的,它破坏了模块的工作方式,也不符合当今图书馆和应用程序的分布方式。
不要忘记,这些JAR的用户仍然需要安装JRE。
jlink
那么,在您的项目中分发一个自定义映像怎么样?它已经包括一个本机JRE和一个启动器了?
你会说,如果你有一个非模块化的项目,那是行不通的。符合事实的但在讨论jpackage之前,让我们先看看这里的两个选项。
运行时插件
这个
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
注意,它依赖于shadow插件,并且还需要一个启动器类。
如果你跑
./gradlew runtimeZip
同样,您可以将此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
正如您所看到的,不需要影子插件或启动器类。您还可以针对其他平台,或者包括非模块依赖项,如下面所示
question
.
包装
到目前为止,还没有GA版本(可能我们必须等待Java 13),但现在有两个选项可用于Java 11或12:
在Java/JavaFX11中,您可以找到Java 12上JPackager的初始工作中的一个后端端口
here
. 有一篇关于使用它的好文章
here
,以及使用它的gradle项目
here
.
对于Java/JavaFX12,已经有了
build 0 version
的
jpackage
Java 13将提供的工具。
这是该工具的初步使用:
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),我可以将其分发以安装:
结论
虽然您可以坚持使用经典的胖罐子,但当迁移到Java11及更高版本时,一切都应该是模块化的。新的(即将推出的)可用工具和插件,包括IDE支持,在这一转变过程中起到了帮助作用。
我知道我在这里介绍了最简单的用例,当尝试更复杂的实际案例时,会有几个问题。。。但我们应该更好地解决这些问题,而不是继续使用过时的解决方案。