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

时间:2019-06-26 11:32:39

标签: java eclipse javafx javafx-11

我正在尝试使我的程序适应Java 12的运行。它当前与Java 8一起运行,并且具有一些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();
        });
    }

}

根据this suggestion,我还使用了Main类来运行。我认为我不需要它,因为HelloFX2不会扩展Application,但这再次与我的实际程序看起来更接近。

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

程序在Eclipse中运行良好。我使用“提取库”选项导出为可运行的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程序发生的错误相同,但是我不需要这样做,因为我不扩展{{1} }。

找不到JavaFX吗? JavaFX类文件都包含在jar中,但是我不确定如何指向它们。

1 个答案:

答案 0 :(得分:2)

使用JavaFX SDK,存在一个lib文件夹,其中包含javafx.base.jarjavafx.controls.jar之类的jar,但是还有诸如libglass.so(Linux)之类的本机库, libglass.dylib(苹果机)。在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/#modular文档。