我有一个Java8应用程序,它使用JavaFX,主类扩展了JavaFX.application.application。目前,我将它作为一个fat jar交付,它在Oracle Java8上运行良好。
现在我希望它能够在OpenJDK11上运行。为了添加JavaFX,我已经将org.openjfx中的工件添加到类路径中,并将它们包含在fat JAR中。如果我从命令行启动我的jar,我会得到
Error: JavaFX runtime components are missing, and are required to run this
application
而我可以用1。作为一种解决办法,我想知道目前(OpenJDK 11)构建/交付非模块化JavaFX应用程序的可执行fat JAR的预期方法是什么。有人能帮忙吗?
以下是打包/分发(非模块化)JavaFX11终端应用程序的几个选项。其中大部分在官方的OpenJFX文档中进行了解释。
我将用这个示例作为参考。我也会用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提到的或这里解释的,现在需要一个不是从application
扩展的launcher类来创建fat JAR。
运行./gradlew jar
将生成一个包含JavaFX类和当前平台的本机库的fat jar(~8 MB)。
您可以像往常一样运行java-jar build/libs/hellofx.jar
,但只能在同一个平台中运行。
正如OpenJFX文档或本文中所解释的,您仍然可以创建跨平台JAR。
在这种情况下,我们可以包括三个图形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"
}
(注意,媒体和Web还具有与平台相关代码/本机库)。
因此,这与以前在Java8上一样工作。但正如我之前所说的,它打破了模块的工作方式,也不符合当前库和应用程序的分布方式。
并且不要忘记,这些JAR的用户仍然必须安装一个JRE。
有了这个建筑.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插件,并且它还需要一个Launcher类。
有关为其他平台构建映像,请参阅targetplatform
。
我们一直认为我们有一个非模块化的项目,这是不能改变的...但如果我们真的改变了呢?
模块化并不是一个很大的改变:您添加了module-info.java
描述符,并且在其上包含了所需的模块,即使这些是非模块化的JAR(基于自动名称)。
基于相同的示例,我将添加一个描述符:
module hellofx {
requires javafx.controls;
exports hellofx;
}
现在我可以在命令行上使用jlink
或使用插件。badass-gradle-plugin是一个gradle plugin,与前面提到的作者相同,它允许创建自定义运行时。
使用此生成文件:
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
最后,有一个新的工具来创建可执行安装程序,您可以使用这些安装程序来分发应用程序。
到目前为止还没有GA版本(我们可能要等到Java13),但是现在有两种选择可以将它与Java11或12一起使用:
对于Java/JavaFX11,在Java12上的JPackager的初始工作中有一个后端口,您可以在这里找到。这里有一篇关于使用它的很好的文章,这里有一个使用它的gradle项目。
这是该工具的一个非常初步的使用:
plugins {
id 'org.openjfx.javafxplugin' version '0.0.5'
}
repositories {
html" target="_blank">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),我可以将其分发安装:
虽然您可以坚持使用经典的fat JAR,但当转移到Java11和更高版本时,一切都应该是模块化的。新的(即将推出的)可用工具和插件,包括IDE支持,在这一过渡过程中起到了帮助作用。
我知道我在这里展示了最简单的用例,当尝试更复杂的实际用例时,会有几个问题...但是,我们应该更好地努力解决这些问题,而不是继续使用过时的解决办法。
我的模块化JavaFX应用程序有问题。我创建了一个JavaFX项目,并添加了JavaFX库和JavaFX模块。但是,我不断收到以下错误消息: 完整设置的图像附于此: 编辑: 以下是所有错误消息: 我还添加了vm选项: 但是,我还是收到了这个错误消息。
我开发并发布了一个使用Apache Batik和JavaCV的Java Swing应用程序。我已经通过java 1.6、7和8对其进行了更新。macOS、Windows和Linux的安装程序是使用Javapackager构建的。Java 8将于1月19日停止支持,我找不到一个解决方案来打包和分发新的LTS版本Java 11。 JavaCV和Batik都不生产模块化jar,但我已经成功地对它们进行了
为缓解 Windows 下路径名过长的 问题, 略微加快一下 require的速度以及隐藏你的源代码,你可以选择把你的应用打包成 asar档案文件,这只需要对你的源代码做一些很小的改动。 大部分用户可以毫不费力地使用这个功能,因为它electron-packager,、electron-forge和electron-builder中都得到了支持,开箱即用。 如果你没有使用这些工具中的任何一个,那么
我的目标是使用JLink将应用程序打包成与自定义JRE捆绑在一起的模块化运行时映像。我的应用程序是一个简单的“Hello World”Java标准版应用程序,依赖于番石榴。我使用JDK11。 基本上,我试图复制Baeldung的教程,但使用NetBeans,Maven管理依赖关系,并使用Maven编译器插件版本3.8.1构建模块系统。 目录结构:
为了完整起见,我使用Oracle JDK 1.8.0_66 for Mac。
问题内容: 我一直在寻找创建模块化Web应用程序的解决方案,该模块是模块化的,即用户可以以简单jar的形式提供自己的插件,然后将其自身的数据提供给我的Web应用程序,而我的webapp将负责用于显示它。 现在的问题是,我希望我的Web应用程序尽可能通用,而不依赖于j2ee Web容器来支持任何内容。即,我不能依靠我的Web容器来提供osgi支持并将Web应用程序作为osgi捆绑包本身部署(这确实使