使用 gradle 6.3、OpenJDK 14 和 OpenJFX 14 部署 JavaFX 应用程序

Posted

技术标签:

【中文标题】使用 gradle 6.3、OpenJDK 14 和 OpenJFX 14 部署 JavaFX 应用程序【英文标题】:Deploy JavaFX application using gradle 6.3, OpenJDK 14 and OpenJFX 14 【发布时间】:2020-09-07 04:18:33 【问题描述】:

我正在使用 gradle 6.3、OpenJDK 14 和 OpenJFX 14 和 IntelliJ 开发 JavaFX 应用程序,我想部署它(创建一个 exe 文件)。

我曾经在 Netbeans 11 下用 JDK 8 制作 JavaFX 应用程序,过程很简单:

    制作应用程序 清理和构建 在 dist 文件夹中查找 jar(当我单击它时,它可以完美运行) 使用 Launch4j 将其转换为 exe 瞧!

由于我要迁移到 OpenJDK 14,我想确保我可以部署我正在制作的应用程序,因此我创建了一个应用程序,并且在我运行它时一切正常(在 IntelliJ 中)。我看到了一些关于如何使用 gradle 部署 javafx 应用程序的教程,我想到了这个过程:

    在 gradle 窗口(屏幕右上角)上,点击 distribution > distZip 在 build\distibutions 中查找生成的 ZIP 文件并解压 您将找到 binlib 文件夹:在 bin 文件夹,我找到了我的项目的 .bat 文件,单击它时,我的应用程序启动并且一切正常。在 lib 文件夹中,我找到了我在项目中使用的所有 jar 文件以及我的 project-name.jar,当我点击它时没有任何反应。

我尝试使用命令行运行它,结果如下:

    C:\Users\Admin\Documents\SmartDoc\build\distributions\SmartDoc-1.0\SmartDoc-1.0\lib>java -jar SmartDoc-1.0.jar
Table PATIENT created successfully !
Table DOSSIER_MEDICAL created successfully !
Table ORDONNANCE created successfully !
Table RENDEZ_VOUS created successfully !
Table SALLE_ATTENTE created successfully !
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: javafx.fxml.LoadException:
file:/C:/Users/Admin/Documents/SmartDoc/build/distributions/SmartDoc-1.0/SmartDoc-1.0/lib/SmartDoc-1.0.jar!/main.fxml:27

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
    at com.smartdoc.gui.Launch.start(Launch.java:27)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:262)
        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:54)
        at javafx.fxml.FXMLLoader$Element.applyProperty(FXMLLoader.java:520)
        at javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:370)
        at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:332)
        at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:242)
        at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:775)
        at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2838)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2557)
        ... 17 more
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at com.sun.javafx.fxml.ModuleHelper.invoke(ModuleHelper.java:100)
        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:258)
        ... 25 more
Caused by: java.lang.UnsupportedOperationException: Cannot resolve 'fa-user-plus'
        at org.kordamp.ikonli.javafx.IkonResolver.resolveIkonHandler(IkonResolver.java:62)
        at org.kordamp.ikonli.javafx.FontIcon.setIconLiteral(FontIcon.java:239)
        ... 31 more

前 5 行是应用程序创建 derby 数据库的结果(运行良好),但在运行应用程序时出现了一些异常。 我也尝试使用--module-path "C:\Program Files\Java\javafx-sdk-14.0.1\lib" --add-modules javafx.controls,javafx.fxml,javafx.base,javafx.graphics 运行,但我遇到了同样的异常。

有 3 个我不知道的解决方案:

    解决此异常 尝试将该 .bat 文件转换为 .exe 文件 新的解决方案

编辑: build.gradle 文件:

plugins 
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'


group 'com.smartdoc'
version '1.0'

repositories 
    mavenCentral()


dependencies 
    compile 'com.calendarfx:calendar:11.8.3'
    compile 'com.calendarfx:view:11.8.3'
    compile 'org.kordamp.ikonli:ikonli-core:11.4.0'
    compile 'org.kordamp.ikonli:ikonli-javafx:11.4.0'
    compile 'org.kordamp.ikonli:ikonli-fontawesome-pack:11.4.0'
    compile 'com.jfoenix:jfoenix:9.0.9'
    compile group: 'org.apache.derby', name: 'derby', version: '10.15.2.0'
    compile group: 'org.apache.derby', name: 'derbyclient', version: '10.15.2.0'
    compile group: 'org.apache.derby', name: 'derbynet', version: '10.15.2.0'

    testCompile group: 'junit', name: 'junit', version: '4.12'


javafx 
    version = "14.0.1"
    modules = ['javafx.controls','javafx.fxml']


mainClassName = "$moduleName/com.smartdoc.Main"

jar 
    manifest 
        attributes "Main-Class": "$mainClassName"
    

    from 
        configurations.runtimeClasspath.collect  it.isDirectory() ? it : zipTree(it) 
    

感谢您的帮助!

【问题讨论】:

如果你想去任何地方轻松开始。尝试让 gradle 任务“运行”运行。这是应用程序插件的任务,与构建 zip 的插件相同。 也许发布 build.gradle。 还要确保在您的 PATH 上有一个 openjdk 14。检查 java -version 的输出。 @Alex 我在帖子中添加了 build.gradle 文件,java -version 是正确的(OpenJDK 14.0.1) @Alex 感谢您的项目,我现在将检查它们 【参考方案1】:

更新 1: 制作一个有效的 .jar 文件

所以我尝试了一些解决方案来使我的 .jar 文件正常工作,我终于找到了 THE ONE:

    在您的 build.gradle 顶部添加:
buildscript 
    repositories 
        jcenter()
    
    dependencies 
        classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
    


plugins 
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'com.github.johnrengelman.shadow' version '5.2.0'


apply plugin : 'com.github.johnrengelman.shadow'

(如您所见,我使用了Gradle Shadow Plugin)

    在 gradle 窗口(intelliJ IDE 的右上角)中,单击 distribution > shadowDistZip 转到build\distributions,你会找到一个ZIP文件(projectName-shadow-version),解压。 打开文件夹,你会发现binlib文件夹,jar到lib文件夹。 您会在那里找到您的 .jar,它的工作原理与您的期望一样。

我还在寻找如何制作.exe,所以如果有人有建议,欢迎!

更新 2: 使用 Launch4j 制作 .exe 文件

我终于设法从我之前创建的 jar 中创建了一个 .exe 文件:我使用了Launch4j(是的,它适用于 Java > 11)。以下是简单的步骤:

    首先下载Launch4j并安装它(不要运行它,它不会工作) 转到 Launch4j 文件,您将看到一个 launch4j.jar 文件,运行它并选择 Basic Tab 选择保存输出的路径(确保最后写.exe) 选择.jar文件所在的路径

    现在转到 JRE 选项卡,在 Min JRE 版本中选择 11.0.1 以确保它仅以 Java > 11 开头,在 Max JRE 版本中选择您想要的最大 Java 版本(在我的情况下,最后一个版本是 14.0.1

    现在单击顶部的齿轮并将配置文件保存在您想要的任何位置,瞧!您的 .exe 文件现在应该可以正常运行了。

PS:您可以使用 Launch4j 添加图标、清单文件和许多其他内容,我只是解释了有史以来最简单的示例,以便你们可以使用它,其余的由您决定: )

如果有其他解决方案,请与我们分享,很多人都在为 JDK 14 的可执行文件而苦恼。

谢谢!

【讨论】:

Launch4j IIRC 有一个 gradle 插件 @Alex 我不知道它存在,我去找找谢谢

以上是关于使用 gradle 6.3、OpenJDK 14 和 OpenJFX 14 部署 JavaFX 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

译文——The Gradle Daemon(守护进程)

Java 8,Gradle 3 上的 Spring Boot 应用程序的 gradle 包装器失败:找不到 cacerts

Mac10.14下使用Xcode10编译调试OpenJDK8最新教程(附源码)

高版本Openjdk缺少tools.jar项目编译不过解决办法

Spring Boot 项目中的 Gradle 无法识别路径中的 Java jdk

开源头条 | OpenJDK 16发布,转向C++14