使用 java11 构建和部署 javafx 应用程序

Posted

技术标签:

【中文标题】使用 java11 构建和部署 javafx 应用程序【英文标题】:Build and deploy javafx application using java11 【发布时间】:2019-04-26 06:17:44 【问题描述】:

我按照https://blog.jetbrains.com/idea/2013/03/packaging-javafx-2-applications-in-intellij-idea-121/中的步骤操作

但是当我尝试在最后一步中构建工件时,我得到了这个错误

错误:Java FX Packager:无法构建工件 - fx:deploy 不是 在这个 JDK 中可用

我知道 JavaFX 已从 java11 中删除,我的问题是我应该如何构建 .jar.exe

这里有一个hello world app 用于快速测试。

【问题讨论】:

1. 我怀疑这太宽泛了,我的意思是,如果您已经意识到 JavaFX 不再与 JDK 捆绑在一起,那么您应该尝试独立的二进制文件。您可以探索 OpenJFX 等较新的选项,并在 Documentation 页面的 JavaFX 和 IntelliJ 部分下找到构建库的指南。 2. 该帖子来自 2013 年,适用于 12.1 版本的 IntelliJ!到现在为止你真的依赖它吗? 我搜索了很多,没有构建 jar 的指南,我发现所有指南都停止在运行应用程序 我已经阅读了您链接的文档,它帮助我运行和开发了应用程序,但我无法在任何地方找到如何构建它。 2.该帖子仍然适用于 java8,我希望它能够正常工作,并且除了最后一步之外所有步骤仍然有效 好的,我将使用 java11 创建一个 hello world JavaFX 应用程序并分享链接 【参考方案1】:

在 Intelij 中不再使用 JavafX JAR 导出选项。您可以使用“具有依赖关系的 Jar-From 模块”将其导出为常规 jar。这将导出一个有效的 Jar,但为了运行它,您需要将 javaFx 路径和模块添加到您的命令中。

获得 jar 后,运行命令应该如下所示:

java --module-path PATH_TO_YOUR_JAVAFX_LIB_FOLDER --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar yourJar.jar

我用这个制作了一个 youtube 教程: https://youtu.be/HGHu-SzL-5E

【讨论】:

谢谢,这就是我正在寻找的解决方案 这很好用,非常感谢。但是有没有办法让jar直接双击就可以运行呢?我曾经能够在 Java 8 上做到这一点。【参考方案2】:

以下方法适用于我在 Windows 和 Ubuntu 上使用 IntelliJ 的 OpenJDK 11 和 OpenJFX 11,并成功创建了一个 jar,该 jar 可以在目标计算机上未安装 JavaFX 的情况下仅使用java -jar filename.jar 运行。请记住,JavaFX jar 依赖于平台。所以Windows jar需要在Windows上编译,Linux jar在Linux上编译。

我的主要方法扩展了应用程序...

public class Main extends Application 

所以,首先创建一个类似于 Start.java 的新 Java 类 - 它链接到原来的 Main 方法。

public class Start 
    public static void main(String[] args)
        Main.main(args);
    

然后你制作 .jar 文件;

文件 > 项目结构 > 工件

单击 + > 选择 JAR > 从具有依赖项的模块

对于 Main 类,选择 Start.java > 点击 Ok

javafx jars 应该被自动提取(如果它们不是手动添加的话)

点击应用并确定

构建 > 构建工件 > 构建

即使在没有安装 JavaFX 的机器上,使用 java -jar filename.jar 创建的文件也应该可以正常运行。

【讨论】:

双击并运行...创建一个快捷方式。在目标框中...C:\Users\me\Desktop\java -jar "C:\Program Files\MyApp\myFX.jar" 在Linux上双击运行chmod +x myFX.jar【参考方案3】:

不幸的是,您将无法以这种方式使用 JFX11 构建您的 jar,因为显然打包程序已从 JFX SDK 中删除。希望它将在未来的版本(可能是 12 版)中实现。阅读此处了解更多详情:

https://youtrack.jetbrains.com/issue/IDEA-200721 包含以下 2 个链接:

https://bugs.openjdk.java.net/browse/JDK-8212780

https://openjdk.java.net/jeps/343

作为临时解决方案,您可以简单地使用/降级到版本 10,它仍然包含所需的打包程序。

【讨论】:

oracle 不再在其网站上托管 java 10。 任何寻找 java10 的人都可以在这里找到它oracle.com/technetwork/java/javase/downloads/…【参考方案4】:

正如 Barosanu240 回答的那样,IntelliJ 目前无法再导出 JavaFX Jars,尽管这方面的开发正在进行中。此外,他在 YouTube 视频上的解决方案效果很好,因此感谢您发布此内容。

为了在不使用命令行的情况下打开 JAR 文件,应用程序本质上需要使用上面列出的附加 JVM 参数重新启动自身。虽然比较杂乱,但可以通过以下方式完成。

假设应用程序在其当前目录中查找一个名为exist.txt 的临时文件。如果此文件不存在,它会创建它,向 CMD 发送命令以使用附加的 JVM 参数启动其自身的另一个实例,然后关闭。然后新打开的实例检查是否存在exist.txt,它现在确实存在;因此,它知道 UI 是开放且可见的。然后它会删除exist.txt,然后应用程序会继续正常运行。

这种方法可以通过 try/catch 块来完成,尽管确实很混乱,如下所示。

try (FileReader fileRead = new FileReader(new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt"))) 
        //If the code gets this far, the file exists. Therefore, the UI is open and visible. The file can now be deleted, for the next time the application starts.

        fileReader.close();
        File file = new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt");
        boolean result = file.delete();
        if (result) 
            System.out.println("File deleted successfully; starting update service.");
         else 
            System.out.println("File was not deleted successfully - please delete exist.txt.");
        

     catch (IOException e) 
        //The file does not exist because an exception was generated. Therefore, create the file, and restart the application using CMD with the additional arguments required
        File file = new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt");
        try 
            boolean result = file.createNewFile();
            if (result) 
                //Start a new instance of this application
                final String command = "cmd /c start cmd.exe /k java --module-path PATH_TO_YOUR_JAVAFX_LIB_FOLDER --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar yourJar.jar;
                Runtime.getRuntime().exec(command);
             else 
                System.out.println("Unable to create exist.txt. Application will close.");
            
         catch (IOException ex) 
            ex.printStackTrace();
        
        //Now that a new file has been created and a command sent to CMD, exit this instance
        System.exit(-1);
    

//The rest of your application's code

请注意,JavaFX lib 文件夹的路径不应包含任何空格。上面的代码需要在您的应用程序的main 方法中,在launch(args) 行之前。可能有更好的方法可以在不使用 try/catch 的情况下实现相同的行为(因为故意调用异常不是好的做法),但这个解决方案暂时可以正常工作。

【讨论】:

【参考方案5】:

我有同样的问题,经过大量搜索后,我在 youtube 上找到了该视频的解决方案,该视频的链接: https://www.youtube.com/watch?v=F8ahBtXkQzU

您必须将计算机上 JavaSDKFX 文件中的所有 (.dill) 文件添加到您要在 Artifact 中设置的库中,查看链接以获得更明显的信息。

【讨论】:

欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted. 我知道了,我以后的答案会更加明显,谢谢。【参考方案6】:

Artifacts -> + -> javaFx Application -> 来自模块 然后设置应用程序类

【讨论】:

以上是关于使用 java11 构建和部署 javafx 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

部署JavaFx应用程序jar

使用 Gradle 构建 JavaFX 应用程序

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

JPackaged JavaFX + Spring boot 不启动

JavaFX概览

JavaFX概览