maven - 使用来自 maven 的 JavaFX11 构建可执行 JAR

标签 maven java-11 javafx-11

我制作了一个使用 Maven、JavaFX 和其他一些依赖项的 Java 应用程序。
以前,构建一个可执行的 jar 很容易,但由于 Java11 是模块化的并且不包含 JavaFX,所以我无法构建一个可以工作的 jar。

我已经尝试了很多东西,但我不知道我现在应该做什么。

我的 pom.xml

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <verbose>true</verbose>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <outputDirectory>out/</outputDirectory>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>fr.crosf32.fxtest.Entry</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

我尝试构建包含所有依赖项的 Artifact ,但运行时出现错误(java -jar):
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: javafx/application/Application
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at fr.crosf32.fxtest.SlimForest.lambda$new$0(SlimForest.java:26)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 11 more

编辑

我尝试使用 Jlink 构建一个包含 JavaFX 的 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 javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:222)
        at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
        ... 1 more
Exception in thread "Thread-0" java.lang.RuntimeException: No toolkit found
        at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:834)

最佳答案

我也在创建可执行 jar 的过程中苦苦挣扎,但是这个解决方法对我有用,我希望它也对你有用:

首先,不要使用 jar插件,我使用了shade pom.xml 中的插件,它会创建一个“fat jar”或“uber jar”,其中包含您的类和 jar 中的所有依赖项。这样,您的 jar 将包含所有必要的 javafx包和类。也就是说,如果您将这些包含在 <dependencies>部分:

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>11</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>11</version>
</dependency>

... 或 javafx 中的任何其他内容运行应用程序所需的库。

然而,仅仅这样做是行不通的。我假设你的主要类(class) Entry extends Application ?

我猜 jar需要知道 的实际 Main 类不 扩展应用程序,所以我刚刚创建了另一个名为 SuperMain 的 Main 类(它只是一个临时名称)调用我原来的主类,即 Main :
// package <your.package.name.here>

public class SuperMain {
    public static void main(String[] args) {
        Main.main(args);
    }
}

而在您的情况下,它是 Entry .

所以在我的 pom.xml 中,我有一个名为 shade 的插件。看起来像这样:
<plugin>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>my.package.name.SuperMain</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

执行 mvn package 后应该有一个“阴影”的 jar .

感谢对这篇文章的回答:JavaFX 11 : Create a jar file with Gradle

希望这可以帮助!

关于maven - 使用来自 maven 的 JavaFX11 构建可执行 JAR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57019143/

相关文章:

java - 无法执行目标 org.codehaus.mojo :exec-maven-plugin:1. 2.1:exec

maven - 带有自签名证书的 tomcat7-maven-plugin

java - 启动tomcat7 :run maven plugin within eclipse and debug

java - Intellij IDEA 中的变量提取到var

java - 在模块路径上使用 OpenJFX 11 JMODS 在 JDK 11 上运行 javafx 示例

java - Gradle如何添加VM选项以在javafx 11 idea上运行和部署jfoenix?

JavaFX 11 : IllegalAccessError when creating Label

java - getAssets 无法在 Android Studio 中工作,但可以在 Eclipse 中工作

java - 通过从 Java 8 到 Java 11 的 CDATA XML 转换处理换行符的变化

java - 如何解决 java.lang.NoClassDefFoundError : javax/xml/bind/JAXBException