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

Abd*_*nna 3 java javafx gradle javafx-11

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

\n\n

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

\n\n
    \n
  1. 提出申请
  2. \n
  3. 清洁和构建
  4. \n
  5. 在 dist 文件夹中查找 jar(当我单击它时效果很好)
  6. \n
  7. 使用 Launch4j 将其转换为 exe
  8. \n
  9. 瞧\xc3\xa0!
  10. \n
\n\n

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

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

我尝试使用命令行运行它,这就是我得到的结果:

\n\n
    C:\\Users\\Admin\\Documents\\SmartDoc\\build\\distributions\\SmartDoc-1.0\\SmartDoc-1.0\\lib>java -jar SmartDoc-1.0.jar\nTable PATIENT created successfully !\nTable DOSSIER_MEDICAL created successfully !\nTable ORDONNANCE created successfully !\nTable RENDEZ_VOUS created successfully !\nTable SALLE_ATTENTE created successfully !\nException in Application start method\nException in thread "main" java.lang.RuntimeException: Exception in Application start method\n        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)\n        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)\n        at java.base/java.lang.Thread.run(Thread.java:832)\nCaused by: javafx.fxml.LoadException:\nfile:/C:/Users/Admin/Documents/SmartDoc/build/distributions/SmartDoc-1.0/SmartDoc-1.0/lib/SmartDoc-1.0.jar!/main.fxml:27\n\n    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)\n    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)\n    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)\n    at com.smartdoc.gui.Launch.start(Launch.java:27)\n    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)\n    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)\n    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)\n    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)\n    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)\n    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)\n    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)\n    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)\n    ... 1 more\nCaused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException\n        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:262)\n        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:54)\n        at javafx.fxml.FXMLLoader$Element.applyProperty(FXMLLoader.java:520)\n        at javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:370)\n        at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:332)\n        at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:242)\n        at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:775)\n        at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2838)\n        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2557)\n        ... 17 more\nCaused by: java.lang.reflect.InvocationTargetException\n        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n        at java.base/java.lang.reflect.Method.invoke(Method.java:564)\n        at com.sun.javafx.fxml.ModuleHelper.invoke(ModuleHelper.java:100)\n        at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:258)\n        ... 25 more\nCaused by: java.lang.UnsupportedOperationException: Cannot resolve \'fa-user-plus\'\n        at org.kordamp.ikonli.javafx.IkonResolver.resolveIkonHandler(IkonResolver.java:62)\n        at org.kordamp.ikonli.javafx.FontIcon.setIconLiteral(FontIcon.java:239)\n        ... 31 more\n
Run Code Online (Sandbox Code Playgroud)\n\n

前 5 行是应用程序创建 derby 数据库的结果(工作完美),但是当运行应用程序时,我遇到了一些异常。\n我也尝试运行,--module-path "C:\\Program Files\\Java\\javafx-sdk-14.0.1\\lib" --add-modules javafx.controls,javafx.fxml,javafx.base,javafx.graphics但得到了相同的异常。

\n\n

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

\n\n
    \n
  1. 解决这个异常
  2. \n
  3. 尝试将该.bat文件转换为.exe文件
  4. \n
  5. 新的解决方案
  6. \n
\n\n

编辑: \nbuild.gradle 文件:

\n\n
plugins {\n    id \'java\'\n    id \'application\'\n    id \'org.openjfx.javafxplugin\' version \'0.0.8\'\n}\n\ngroup \'com.smartdoc\'\nversion \'1.0\'\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    compile \'com.calendarfx:calendar:11.8.3\'\n    compile \'com.calendarfx:view:11.8.3\'\n    compile \'org.kordamp.ikonli:ikonli-core:11.4.0\'\n    compile \'org.kordamp.ikonli:ikonli-javafx:11.4.0\'\n    compile \'org.kordamp.ikonli:ikonli-fontawesome-pack:11.4.0\'\n    compile \'com.jfoenix:jfoenix:9.0.9\'\n    compile group: \'org.apache.derby\', name: \'derby\', version: \'10.15.2.0\'\n    compile group: \'org.apache.derby\', name: \'derbyclient\', version: \'10.15.2.0\'\n    compile group: \'org.apache.derby\', name: \'derbynet\', version: \'10.15.2.0\'\n\n    testCompile group: \'junit\', name: \'junit\', version: \'4.12\'\n}\n\njavafx {\n    version = "14.0.1"\n    modules = [\'javafx.controls\',\'javafx.fxml\']\n}\n\nmainClassName = "$moduleName/com.smartdoc.Main"\n\njar {\n    manifest {\n        attributes "Main-Class": "$mainClassName"\n    }\n\n    from {\n        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

感谢您的帮助!

\n

Abd*_*nna 5

更新 1:制作工作 .jar 文件

\n\n

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

\n\n
    \n
  1. 将以下内容添加到build.gradle的顶部:
  2. \n
\n\n
buildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath \'com.github.jengelman.gradle.plugins:shadow:5.2.0\'\n    }\n}\n\nplugins {\n    id \'application\'\n    id \'org.openjfx.javafxplugin\' version \'0.0.8\'\n    id \'com.github.johnrengelman.shadow\' version \'5.2.0\'\n}\n\napply plugin : \'com.github.johnrengelman.shadow\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
    \n
  1. 在 gradle 窗口(intelliJ IDE 的右上角)中,单击distribution > ShadowDistZip
  2. \n
  3. 进入build\\distributions,你会发现一个ZIP文件({projectName}-shadow-{version}),解压它。
  4. \n
  5. 打开该文件夹,您将找到binlib文件夹,转到lib文件夹中的 jar。
  6. \n
  7. 您会发现您的.jar可以按照您的期望工作。
  8. \n
\n\n

我仍在寻找如何使其成为.exe,所以如果有人有建议,欢迎!

\n\n

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

\n\n

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

\n\n
    \n
  1. 首先下载Launch4j并安装它(不要运行它,它不会工作)
  2. \n
  3. 转到 Launch4j 文件,您将看到一个launch4j.jar文件,运行它并选择Basic Tab
  4. \n
  5. 选择保存输出的路径(确保在末尾写入.exe)
  6. \n
  7. 选择.jar文件所在的路径
  8. \n
\n\n

快速示例

\n\n
    \n
  1. 现在转到JRE选项卡,在 Min JRE 版本中选择 11.0.1 以确保它仅以 Java > 11 启动,然后在 Max JRE 版本中选择您想要的最大 Java 版本(在我的例子中,最后一个版本是 14.0.1)。 1
  2. \n
\n\n

JRE示例

\n\n
    \n
  1. 现在单击顶部的齿轮并将配置文件保存在您想要的任何位置,Voil\xc3\xa0!您的 .exe 文件现在应该运行得很好。
  2. \n
\n\n

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

\n\n

如果还有其他解决方案,请与我们分享,很多人都在使用 JDK 14 和可执行文件。

\n\n

谢谢你!

\n