【问题标题】:JavaFX application runs fine when running Main in IntelliJ, built jar doesn't runJavaFX 应用程序在 IntelliJ 中运行 Main 时运行良好,构建的 jar 不运行
【发布时间】:2019-08-21 08:40:09
【问题描述】:

过去几个小时我一直在尝试修复此错误,但没有成功。

首先,我创建了一个 Maven 项目,在其中添加了所需的 JavaFX 依赖项 (POM.xml)

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>groupId</groupId>
<artifactId>STTGui</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>


<build>
    <!-- Maven Plugin configuration is required, without it an internal java error is thrown -->
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <release>12</release>
            </configuration>
        </plugin>

        <!-- Maven Shade Plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <executions>
                <!-- Run shade goal on package phase -->
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <!-- add Main-Class to manifest file -->
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>speechToText.userInterface.MainEntry</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.3</version>
            <configuration>
                <mainClass>speechToText.userInterface.MainEntry</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>maven-cognitiveservices-speech</id>
        <name>Microsoft Cognitive Services Speech Maven Repository</name>
        <url>https://csspeechstorage.blob.core.windows.net/maven/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.microsoft.cognitiveservices.speech</groupId>
        <artifactId>client-sdk</artifactId>
        <version>1.6.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>12.0.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-media -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-media</artifactId>
        <version>12.0.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-graphics -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-graphics</artifactId>
        <version>12.0.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>12.0.2</version>
    </dependency>

</dependencies>
</project>  

我还添加了module-info.java:

module SSTGui {
    requires javafx.controls;
    requires javafx.fxml;
    requires client.sdk;
    opens speechToText.userInterface to javafx.fxml;
    exports speechToText.userInterface;
}

当我在 IDE 中执行 JavaFX 应用程序时,一切正常,当我使用 maven -&gt; lifecycle -&gt;package 构建 Jar 时,jar 构建但在执行时出现以下错误:

错误:缺少 JavaFX 运行时组件,需要运行此应用程序

想法:
1) 安装 OPENJDK,因为 Java JDK 不再包含用于 JavaFX 的运行时组件 -> 没有'不会导致任何变化。
2) 使用 GLUON 的 OpenJFX SDK 代替 Maven,也没有解决,同样的问题。

我想不知何故,依赖项没有打包在 JAR 中,这就是为什么它现在可以工作,但我无法解决它,知道吗

编辑我添加了`maven shade插件来创建一个胖罐子:

<!-- Maven Shade Plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <executions>
                <!-- Run shade goal on package phase -->
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <!-- add Main-Class to manifest file -->
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>speechToText.userInterface.Main</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>  

但是在构建完成并创建了两个 jar 之后:original-name.jarname.jar 当我执行 name.jar 时,出现以下错误:

线程“main”java.lang.SecurityException 中的异常:Manifest 主要属性的签名文件摘要无效

当执行original-name.jar 我得到:

没有主清单属性,在 original-STTGui-1.0-SNAPSHOT.jar 中

为了解决这个问题,我尝试实现一个 Helper 主类,它不从启动我的原生 main 的 Application 扩展:

package speechToText.userInterface;

public class MainEntry {

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

我还将maven-shade-plugin 中的&lt;mainClass&gt; 属性更改为此类以及javafx-plugin 中的属性。

【问题讨论】:

  • 你是对的,jar 不包含 JavaFX 依赖项。您可以为此使用阴影插件(请参阅this question),甚至更好,因为您有一个模块化应用程序,您可以运行mvn javafx:jlink 来创建自定义图像(请参阅doc)。
  • @JoséPereda using mvn javafx:jlink 抛出:错误:自动模块不能与 jlink 一起使用:client.sdk(我的认知语音服务)+ 无法执行目标 org.openjfx:javafx-maven-plugin: 0.0.3:jlink
  • 那你就不能直接使用jlink了。有更复杂的选项可以从非模块化依赖项中创建模块,但现在我想你可以只做一个胖 jar。
  • @JoséPereda 我尝试了阴影插件,并更新了我的问题。首先生成了两个 JAR,虽然我不知道为什么一个被命名为 STT...jar 和另一个 original-STT...jar 并且在执行 STT..jar 之后我得到Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
  • 对于初学者,您需要使用 Launcher 类(请参阅我之前链接的问题)。不能说什么是 SST,你应该得到一个“胖” jar(以 MB 为单位),你可以用java -jar yourFatJar.jar 运行它。您是否有机会使用 AdoptOpenJDK?

标签: java maven javafx


【解决方案1】:

根据 cmets,此答案收集了解决问题所需的一些提示。

Jlink 错误

关于分发:理想情况下,您应该使用jlink 分发您的应用程序,创建自定义运行时映像。但是运行mvn javafx:jlink 会给出:

错误:自动模块不能与 jlink 一起使用:client.sdk

即使您的应用程序是模块化的,也并不意味着所有依赖项也是模块化的,因此mvn javafx:jlink 可能无法正常工作。但是,使用模块化方法有几个选项可以做到这一点:

基于这个问题Is there a way to add maven dependencies while using the maven-jlink-plugin?,您可以尝试从失败的client.sdk 自动模块中创建一个模块,但这并非易事。

另一个可供探索的选项:使用jpackage (early access),即使它不是模块化的,您也可以创建项目的安装程序。但是,这需要 JDK 14 的早期版本...

此时,uber/fat jar 的经典解决方案似乎是最简单的方法。

JavaFX 依赖项错误

但是,在使用mvn package 并运行 jar 之后:

错误:JavaFX 运行时组件丢失,是运行此应用程序所必需的

基本上:

  • jar 不包含 JavaFX 依赖项
  • 如果主类从 Application 扩展,即使这样做,它也不会起作用。

这个问题Maven Shade JavaFX runtime components are missing已经解决了。

因此您需要添加maven-shade-plugin 以捆绑JavaFX 依赖项,并且您需要添加Launcher 或不从Application 扩展的入口点类。

清单错误

关于错误:

线程“main”java.lang.SecurityException 中的异常:Manifest 主要属性的签名文件摘要无效

另一个问题“Invalid signature file” when attempting to run a .jar 为您提供了解决阴影插件问题的解决方案,方法是添加一个排除清单签名文件的过滤器。

一旦所有错误都解决了,你应该可以运行了:

mvn package
java -jar target/yourJar.jar

【讨论】:

  • 完美!谢谢!
猜你喜欢
  • 2021-06-12
  • 1970-01-01
  • 2015-01-03
  • 2012-01-18
  • 2016-10-26
  • 2020-04-02
  • 2013-07-27
  • 2016-05-26
  • 1970-01-01
相关资源
最近更新 更多