当前位置: 首页 > 知识库问答 >
问题:

Java 12和JavaFX 12-创建可运行的jar和自定义JRE

景信瑞
2023-03-14

我正在尝试调整我的程序,使其能与Java12一起运行。它目前与Java8一起运行,并且有一些JavaFX组件(一些对话框)。它不是模块化的。我的IDE是Eclipse,JavaFX jar文件作为用户库包含在构建路径中。我想生成一个可运行的jar,或者将javafx文件捆绑在其中,或者将它们添加到自定义JRE,这样我就可以分发它,而不需要最终用户单独安装Java12或javafx。

首先,我想我应该尝试一个简单的HelloFX程序,修改后更像我的程序。

public class HelloFX2 {

    public HelloFX2() {
        startToolkit();

        // have to wait a second for the JavaFX thread to actually start, or else the Platform.runLater throws an exception
        try
        {
            Thread.sleep(1000);
        }
        catch(InterruptedException ex)
        {
            Thread.currentThread().interrupt();
        }

        // create the scene and display
        Platform.runLater(() -> {
            Scene theScene = createTheScene();
            final Stage stage = new Stage();
            stage.setScene(theScene);
            stage.show();
        });

    }

    public Scene createTheScene() {
        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
        Scene scene = new Scene(new StackPane(l), 640, 480);
        return scene;
    }

    public void startToolkit () {
        // we can only create a Scene in a JavaFX thread
        SwingUtilities.invokeLater(() -> {

            // Initialize FX Toolkit, so that we can use the Java FX objects
            new JFXPanel();
        });
    }

}

根据这个建议,我还使用了一个Main类来运行。我认为在我的例子中不需要它,因为HelloFX2没有扩展application,但这更接近于我的实际程序的样子。

public class Main2 {
    public static void main(String[] args) {
        HelloFX2 theApp = new HelloFX2();
    }
}

该程序在Eclipse中运行良好。我使用“extract libraries”选项导出为可运行的JAR文件,然后使用jdepsjlink创建自定义JRE:

D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jdeps" --ignore-missing-deps --print-module-deps HelloFX2.jar
java.base,java.desktop

D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jlink" --no-header-files --no-man-pages  --add-modules java.base,java.desktop --output java-runtime

但当我尝试运行它时,我得到了这个错误:

D:\Work\Java12>"java-runtime\bin\java" -jar HelloFX2.jar
Graphics Device initialization failed for :  d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
        at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
        at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:243)
        at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
        at javafx.embed.swing.JFXPanel.lambda$initFx$1(JFXPanel.java:224)
        at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
        at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
        at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
        ... 1 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: No toolkit found
        at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
        at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
        at javafx.embed.swing.JFXPanel.lambda$initFx$1(JFXPanel.java:224)
        at java.base/java.lang.Thread.run(Thread.java:835)

当您没有将--module-path开关添加到命令行时,这与原始HelloFX程序出现的错误相同,但我不需要它,因为我没有扩展application

共有1个答案

禹兴安
2023-03-14

使用JavaFX SDK,有一个lib文件夹,其中包含诸如JavaFX.base.jarJavaFX.controls.jar之类的JAR,但也有诸如libglass.so(Linux)、libglass.dylib(Mac)之类的本机库。在Windows上,本机DLL(如glass.dll)位于bin文件夹中。

当将这些类打包到一个胖罐子中时,您还必须考虑到所需的本机库。

这意味着您必须为javafx.graphics打包本机库,但如果不使用javafx.web模块,则不需要包含webkit库(增加大约80 MB)。

还要注意,这些库是特定于平台的(甚至是JAR)。如果您想将jar分发到其他平台,您也可以打包这些平台的类和本机库,只需下载它们的SDK。

所有这些都在https://openjfx.io/openjfx-docs/#modular的非模块化项目-命令行一节中详细解释。

对于模块化项目,jlink是推荐的工具。在这两种情况下,使用构建工具(Gradle/Maven)确实有助于处理JavaFX依赖项:您不需要JavaFX SDK,因为您将从Maven Central检索依赖项,并且这些工具已经将本机库与它们捆绑在一起。同样,值得阅读整个https://openjfx.io/openjfx-docs/#模块化文档。

 类似资料:
  • 这里的一些文章建议使用“Application”插件,但这并不完全导致我预期的结果(只是一个JAR,没有启动脚本或诸如此类的东西)。 我如何才能获得与Eclipse使用“export...”相同的结果。对话?

  • 问题内容: 到目前为止,我已经通过Eclipse的“导出…”功能创建了可运行的JAR文件,但是现在我切换到IntelliJ IDEA和Gradle进行构建自动化。 这里的一些文章建议使用“应用程序”插件,但这并不能完全导致我期望的结果(只是JAR,没有启动脚本或类似的东西)。 如何通过Eclipse的“导出…”对话框获得相同的结果? 问题答案: 可执行jar文件只是清单中包含Main- Class

  • 问题内容: 我想使用码头来启动我的应用程序,因此我添加了下面提到的依赖项。当我运行主要方法Jetty成功启动时(我正在一个struts2 + spring3 + hibernate maven项目中,我也可以将其部署在tomcat中) 现在,我想从war包装pom创建一个可执行jar。所以我在pom中添加了maven-assembly-plugin。(我尝试使用maven jar插件,但未添加依赖

  • 问题内容: 使用Maven 3.1 Eclipse Helios Aspekt: 尝试使用maven-jar / dependency-plugins创建可运行的jar文件。 问题: 创建jar文件和依赖项后,当我尝试使用命令启动jar文件时出现NoCLassDefFoundErrors 但是类/文件可以在./dependency-jars文件夹中找到???我还尝试了以下命令: 这也不起作用。 题

  • 嗯,我尝试了这么多的方法来创建可执行jar,但4个小时后我放弃了。我正在尝试用我的项目制作可执行的jar文件,其中主类在控制器中。基本上,我尝试使用export/runnable JAR文件,并使用各种选项,包括生成ant脚本。我在终端总是有类似的错误 当我用终端运行时 java-jar fruitstore.jar 提前感谢您的迅速回复

  • 我的要求是像这样分析句子。“给我找一本饥饿的潮汐书。”或者“饥饿的潮水或破碎的镜子,哪一个更好。”饥饿的潮汐和破碎的镜子是书的名字,为此我需要创建一个自定义模型,在给定的令牌数组中找到书的标题。因此,稍后我可以根据给定的句子创建一个查询。请让我知道我如何做到这一点,或者如果有任何其他方法来分析这样的句子。