缺少 Maven Shade JavaFX 运行时组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52653836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:33:25  来源:igfitidea点击:

Maven Shade JavaFX runtime components are missing

javamavenjavafxjavafx-11

提问by Bitclef

I'm trying to create a JFX11 self-containing jar using maven dependencies. From the research I've done, it seems the best way to do this is through the maven shade plugin. However, When I run it, I get the this error:

我正在尝试使用 maven 依赖项创建一个 JFX11 自包含 jar。根据我所做的研究,似乎最好的方法是通过 maven shade 插件。但是,当我运行它时,出现此错误:

Error: JavaFX runtime components are missing, and are required to run this application

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

I don't understand why this is happening. What am I messing up? Is there a better way to do this? I've also tried the maven assembly plugin with the same message.

我不明白为什么会这样。我在捣乱什么?有一个更好的方法吗?我还尝试了具有相同消息的 Maven 程序集插件。

pom file for reference

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>Application</groupId>
    <artifactId>Main</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpaceRunner</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>10</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>Application.Main</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>
                                Application.Main
                            </mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>Application.Main</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

采纳答案by José Pereda

This answerexplains why a fat/uber jar fails on JavaFX 11. In short:

这个答案解释了为什么一个 fat/uber jar 在 JavaFX 11 上失败了。简而言之:

This error comes from sun.launcher.LauncherHelper in the java.base module. The reason for this is that the Main app extends Application and has a main method. If that is the case, the LauncherHelper will check for the javafx.graphicsmodule to be present as a named module. If that module is not present, the launch is aborted.

此错误来自 java.base 模块中的 sun.launcher.LauncherHelper。这样做的原因是 Main 应用程序扩展了 Application 并有一个 main 方法。如果是这种情况,LauncherHelper 将检查javafx.graphics模块是否作为命名模块存在。如果该模块不存在,则中止启动。

And already proposes a fix for Gradle.

并且已经为 Gradle 提出了修复方案。

For Maven the solution is exactly the same: provide a new main class that doesn't extend from Application.

对于 Maven,解决方案完全相同:提供一个不从Application.

You will have new class in your applicationpackage (bad name):

您的application包中将有新类(坏名):

// NewMain.java
public class NewMain {

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

And your existing Mainclass, as is:

和您现有的Main课程,原样:

//Main.java
public class Main extends Application {

    @Override
    public void start(Stage stage) {
        ...
    }

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

Now you need to modify your pom and set your main class for the different plugins:

现在你需要修改你的 pom 并为不同的插件设置你的主类:

<mainClass>application.NewMain</mainClass>

Platform-specific Fat jar

平台特定的 Fat jar

Finally, with the shade plugin you are going to produce a fat jar, on your machine.

最后,使用 shade 插件,您将在您的机器上生成一个胖罐。

This means that, so far, your JavaFX dependencies are using a unique classifier. If for instance you are on Windows, Maven will be using internally the winclassifier. This has the effect of including only the native libraries for Windows.

这意味着,到目前为止,您的 JavaFX 依赖项使用的是唯一的分类器。例如,如果您使用的是 Windows,Maven 将在内部使用win分类器。这具有仅包含适用于 Windows 的本机库的效果。

So you are using:

所以你正在使用:

  • org.openjfx:javafx-controls:11
  • org.openjfx:javafx-controls:11:win
  • org.openjfx:javafx-graphics:11
  • org.openjfx:javafx-graphics:11:win <-- this contains the native dlls for Windows
  • org.openjfx:javafx-base:11
  • org.openjfx:javafx-base:11:win
  • org.openjfx:javafx-controls:11
  • org.openjfx:javafx-controls:11:win
  • org.openjfx:javafx-graphics:11
  • org.openjfx:javafx-graphics:11:win <-- 这包含 Windows 的本机 dll
  • org.openjfx:javafx-base:11
  • org.openjfx:javafx-base:11:win

Now, if you produce the fat jar, you will bundle all those dependencies (and those other regular third party dependencies from your project), and you will be able to run your project as:

现在,如果您生成胖 jar,您将捆绑所有这些依赖项(以及您项目中的其他常规第三方依赖项),并且您将能够以以下方式运行您的项目:

java -jar myFatJar-1.0-SNAPSHOT.jar

While this is very nice, if you want to distribute you jar, be aware that this jar is notcross-platform, and it will work only on your platform, in this case Windows.

虽然这很好,但如果你想分发你的 jar,请注意这个 jar不是跨平台的,它只能在你的平台上工作,在这种情况下是 Windows。

Cross-Platform Fat Jar

跨平台 Fat Jar

There is a solution to generate a cross-platform jar that you can distribute: include the rest of the native libraries of the other platforms.

有一个解决方案可以生成一个可以分发的跨平台 jar:包括其他平台的其余本机库。

This can be easily done, as you just need to include the graphics module dependencies for the three platforms:

这很容易完成,因为您只需要包含三个平台的图形模块依赖项:

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</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>

Size

尺寸

There is a main issue with this approach: the size. As you can see in this other answer, if you use the WebView control, you will be bundling around 220 MB due to the WebKit native libraries.

这种方法有一个主要问题:大小。正如您在另一个答案中看到的,如果您使用 WebView 控件,由于 WebKit 本机库,您将捆绑大约 220 MB。