【问题标题】:Not able to generate cross platform javaFX application无法生成跨平台 javaFX 应用程序
【发布时间】:2021-02-21 15:07:18
【问题描述】:

我似乎无法从 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 插件将所有依赖项打包在一个胖罐中。

在实际的 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 类,它调用扩展应用程序的实际类:

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>

【问题讨论】:

  • 我没有尝试过,但我认为这是可能的。它似乎记录在(在一定程度上)openjfx.io | Runtime images | Custom JDK+JFX Images | Cross-platform jar。我认为问题中发布的 maven 文件可能大部分是正确的,它只需要删除配置文件,以便所有平台的所有 jar 都放在生成的 Jar 中。
  • 我删除了配置文件并将每个依赖项添加了 3 次(win、linux 和 mac),但我得到了与以前相同的警告,基本上说有重叠的类将被删除,结果jar 仅适用于 linux。最后,我为 linux、mac、win 或它们三个编译它都没有关系,生成的 jar 总是相同的大小,它只适用于 linux。
  • 重叠类的警告指出“通常这无害,您可以跳过这些警告”,我认为这里就是这种情况。如果您的 maven 项目是正确的,则唯一的本机库将不会重叠并且应该被复制,即使有警告也是如此。如果它是跨平台的,那么您不应该为 linux、mac 或 windows 进行编译。相反,您为所有三个编译一次,只生成一个适用于所有平台的 jar。这个单一的 jar 应该包含所有平台的本机库,因此 jar 文件大小不会因平台而异。
  • 如果您需要进一步的帮助,请提供minimal reproducible example,其中还包括您的应用程序代码。
  • 另外请注意,我提到的跨平台 jar 的文档指出:“为了创建具有所有必需 JavaFX 依赖项的可运行 jar,您需要使用不t 从应用程序扩展。”我从来没有这样做过,所以我对此没有任何建议,但这就是我要求最小可重现示例的原因之一,那么至少有人可以看到你的启动器类是什么。

标签: java maven javafx-11


【解决方案1】:

AFAIK 无法再为 JavaFX 应用程序创建跨平台 JAR。

但是应该可以创建特定于平台的 JAR。

我对Shade Plugin不是很熟悉,但是根据docs应该可以排除依赖。

例如对于 mac 版本,请确保排除所有非 mac javafx 依赖项。

【讨论】:

  • 我试图排除任何与已编译操作系统无关的依赖项,但仍然得到相同的结果。即使我指定 mac 或 win,它也只能在 linux 上运行,并且无论我使用什么配置文件,生成的 jar 始终具有相同的大小。
【解决方案2】:

正如@jewelsea 在评论中提供的one of the links 中所建议的那样,诀窍是独立显式添加每个平台的图形模块。

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>11</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>11</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics</artifactId>
        <version>11</version>
        <classifier>win</classifier>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics</artifactId>
        <version>11</version>
        <classifier>linux</classifier>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics</artifactId>
        <version>11</version>
        <classifier>mac</classifier>
    </dependency>
</dependencies>

它会生成一个胖 jar,我终于可以看到里面的 .dll 文件了。在 linux 和 mac 上试过,在两个平台上都可以使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多