使用 JavaFX11 从 Maven 构建可执行 JAR
Build executable JAR with JavaFX11 from maven
我制作了一个 Java 应用程序,它使用 Maven、JavaFX 和其他一些依赖项。
以前,构建可执行 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>
我试图构建内部包含所有依赖项的工件,但是当我 运行 (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[=11=](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(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(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
我在创建可执行 jar 的过程中也遇到了困难,但这个解决方法对我有用,我希望它对你也有用:
首先,我没有使用 jar
插件,而是在 pom.xml
中使用了 shade
插件,它创建了一个 "fat jar" 或 "uber jar"包含您的 classes 和 jar 中的所有依赖项。这样,您的 jar 将包含在所有必需的 javafx
包和 class 中。也就是说,如果您将这些包含在 <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 class 而 不会 扩展应用程序,所以我刚刚创建了另一个名为 SuperMain
的 Main class(它只是一个临时名称) 调用了我原来的 main class,它是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
.
后应该会有一个 "shaded" 的 jar
感谢对此 post 的回答:
希望对您有所帮助!
即使这是很久以前的事了,但也许还有其他人在搜索这个答案:你必须在你的 pom.xml 中包含 os 分类器,这里有一个很好的教程:
https://youtu.be/w_PsCNqqcE4?list=PL4h6ypqTi3RR_bhBk6PtLfD83YkaJXXxw
我制作了一个 Java 应用程序,它使用 Maven、JavaFX 和其他一些依赖项。 以前,构建可执行 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>
我试图构建内部包含所有依赖项的工件,但是当我 运行 (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[=11=](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(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(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
我在创建可执行 jar 的过程中也遇到了困难,但这个解决方法对我有用,我希望它对你也有用:
首先,我没有使用 jar
插件,而是在 pom.xml
中使用了 shade
插件,它创建了一个 "fat jar" 或 "uber jar"包含您的 classes 和 jar 中的所有依赖项。这样,您的 jar 将包含在所有必需的 javafx
包和 class 中。也就是说,如果您将这些包含在 <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 class 而 不会 扩展应用程序,所以我刚刚创建了另一个名为 SuperMain
的 Main class(它只是一个临时名称) 调用了我原来的 main class,它是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
.
感谢对此 post 的回答:
希望对您有所帮助!
即使这是很久以前的事了,但也许还有其他人在搜索这个答案:你必须在你的 pom.xml 中包含 os 分类器,这里有一个很好的教程:
https://youtu.be/w_PsCNqqcE4?list=PL4h6ypqTi3RR_bhBk6PtLfD83YkaJXXxw