我似乎无法生成一个跨平台的JavaFX应用程序。
当我在IntelliJ中运行它时,它正常工作,如果通过maven打包,我也可以在Linux上运行生成的jar文件。
问题出现在我尝试在Mac上运行jar文件时,似乎没有包含JavaFX库,然后我会得到这个堆栈跟踪:
Graphics Device initialization failed for : es2, 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:244)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:261)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:832)
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 “main” java.lang.RuntimeException: No toolkit found
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:273)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:832)
我正在使用Java 15编译为11以及JavaFX11。
我还使用maven配置文件来生成特定版本,并使用shade插件将所有依赖项打包成一个fat jar文件。
此外,还有一个启动器,它是清单指向的位置,在实际的FX应用程序之前运行。
这是pom文件的样子。
<profiles>
<profile>
<id>linux</id>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
</dependencies>
</profile>
<profile>
<id>mac</id>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
</dependencies>
</profile>
<profile>
<id>win</id>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.log.Launcher</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
我还注意到无论我选择哪个配置文件,它总是生成Linux版本,并且我可以看到这个Maven日志:
[WARNING] javafx-controls-11-win.jar, javafx-graphics-11-linux.jar, javafx-fxml-11-linux.jar, LogAnalyzer-1.0-SNAPSHOT.jar, javafx-base-11-linux.jar, javafx-controls-11-linux.jar, javafx-fxml-11-win.jar define 1 overlapping classes:
[WARNING] - module-info
[WARNING] javafx-controls-11-win.jar, javafx-controls-11-linux.jar define 1216 overlapping classes:
[WARNING] - com.sun.javafx.scene.control.TableColumnBaseHelper$TableColumnBaseAccessor
[WARNING] - javafx.scene.control.ComboBoxBase
[WARNING] - javafx.scene.control.skin.ColorPickerSkin$StyleableProperties$2
[WARNING] - com.sun.javafx.scene.control.inputmap.InputMap$KeyMappingInterceptor
[WARNING] - javafx.scene.control.cell.ChoiceBoxTreeTableCell
[WARNING] - javafx.scene.control.TableCell$3
[WARNING] - javafx.scene.control.skin.ProgressBarSkin$StyleableProperties$1
[WARNING] - javafx.scene.control.DialogPane$2
[WARNING] - javafx.scene.control.skin.ToolBarSkin$4
[WARNING] - javafx.scene.control.skin.ColorPickerSkin$3
[WARNING] - 1206 more...
[WARNING] javafx-fxml-11-linux.jar, javafx-fxml-11-win.jar define 80 overlapping classes:
[WARNING] - com.sun.javafx.fxml.expression.ExpressionValue$KeyPathMonitor
[WARNING] - javafx.fxml.FXMLLoader$RootElement
[WARNING] - com.sun.javafx.fxml.expression.Expression$Parser$TokenType
[WARNING] - javafx.fxml.FXMLLoader$DefineElement
[WARNING] - javafx.fxml.Initializable
[WARNING] - javafx.fxml.FXMLLoader$ControllerMethodEventHandler
[WARNING] - com.sun.javafx.fxml.BeanAdapter
[WARNING] - javafx.fxml.FXMLLoader$ControllerAccessor$1
[WARNING] - javafx.fxml.JavaFXBuilderFactory$ObjectBuilderWrapper$ObjectBuilder
[WARNING] - javafx.fxml.FXML
[WARNING] - 70 more...
[WARNING] maven-shade-plugin has detected that some class files are
[WARNING] present in two or more JARs. When this happens, only one
[WARNING] single version of the class is copied to the uber jar.
[WARNING] Usually this is not harmful and you can skip these warnings,
[WARNING] otherwise try to manually exclude artifacts based on
[WARNING] mvn dependency:tree -Ddetail=true and the above output.
[WARNING] See http://maven.apache.org/plugins/maven-shade-plugin/
我一直在阅读其他帖子和观看一些视频,发现其他人也遇到了这个问题,但对我来说似乎有点奇怪。另外奇怪的是,当我生成Windows版本时,在生成的jar文件中看不到任何.dll文件。
有人知道如何生成跨平台的FX jar包吗?
-------- 编辑 --------
正如其他帖子中建议的那样,我有一个启动器类(Launcher class),它调用扩展Application类的实际类:
public class Launcher {
public static void main(String[] args) {
App.main(args);
}
}
还有JavaFX类:
public class App extends Application {
public static void main(String[] args) {
Application.launch();
}
@Override
public void start(Stage stage) throws IOException {
...
}
}
我现在已经从pom文件中移除了配置文件,所以在编译时,maven应该会使用所有依赖项(mac、linux和win),但是似乎仍然只生成了linux的依赖项(我正在Linux系统下运行,这可能与此有关),因为如果我打开jar文件,我看不到任何.dll文件,并且它仍然无法在mac上运行。以下是我的完整pom文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.log</groupId>
<artifactId>LogAnalyzer</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>org.log.Launcher</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>