简体   繁体   English

多模块JavaFX maven项目打包问题

[英]Multi-module JavaFX maven project packaging issue

This is an attempt to create a multi-module JavaFX application with maven.这是尝试使用 maven 创建多模块 JavaFX 应用程序。

Given the following structure of the project:鉴于项目的以下结构:

project
|  pom1.xml
|_____ Word Generator (Folder)
      |  pom2.xml
      |_____logic (folder)
            |  WordGenerator
|_____UI (folder)
      |  pom3.xml
      |_____marty  
            |  App
            |  PrimaryController
            |  SecondaryController

We have the following structure of the pom files in order of the scheme above:按照上述方案的顺序,我们有以下 pom 文件的结构:

pom1.xml pom1.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>org.games.marty</groupId>
    <artifactId>words</artifactId>
    <packaging>pom</packaging>
    <version>0.1</version>

    <modules>
        <module>UI</module>
        <module>Word Generator</module>
    </modules>

    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>16</source>
                        <target>16</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

pom2.xml pom2.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">
    <parent>
        <artifactId>words</artifactId>
        <groupId>org.games.marty</groupId>
        <version>0.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>word.generator</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>16</source>
                        <target>16</target>
                    </configuration>
                </plugin>
                <plugin>
                    <!-- Build an executable JAR -->
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.1.0</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <addClasspath>true</addClasspath>
                                <classpathPrefix>lib/</classpathPrefix>
                                <mainClass>org.games.marty.logic.WordGenerator</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

pom3.xml pom3.xml

<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>
    <artifactId>UI</artifactId>
    <version>0.1</version>

    <parent>
        <artifactId>words</artifactId>
        <groupId>org.games.marty</groupId>
        <version>0.1</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>16</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>16</version>
        </dependency>
        <dependency>
            <groupId>org.games.marty</groupId>
            <artifactId>word.generator</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>16</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.6</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running -->
                        <!-- Usage: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>org.games.marty.App</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- Build an executable JAR -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>org.games.marty.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The way we have attempted to build the application in order for the UI to have access to the WordGenerator logic is to maven package the result from the pom1.xml directive我们尝试构建应用程序以使 UI 能够访问 WordGenerator 逻辑的方法是将 pom1.xml 指令的结果 maven package

We get the above error as mentioned earlier:我们得到了前面提到的上述错误:

Error: Could not find or load main class org.games.marty.App
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

As far as my understanding goes, the JavaFX dependencies are installed throught maven and should be available but they are missing?就我的理解而言,JavaFX 依赖项是通过 maven 安装的,应该可用,但它们丢失了?

Packaging via mvn package using the maven-jar-plugin is not enough使用maven-jar-plugin通过mvn package是不够的

mvn package , by default, is just going to package the jar for your application code, it isn't going to include all of the dependant library code (which is why the dependent code cannot be found when you attempt to run your application).默认情况下, mvn package只会为您的应用程序代码打包 jar,它不会包含所有依赖库代码(这就是为什么在您尝试运行应用程序时找不到依赖代码的原因)。

You could package your application code and dependant libraries using an assembly, as detailed in How can I create an executable JAR with dependencies using Maven?您可以使用程序集打包应用程序代码和依赖库,如如何使用 Maven 创建具有依赖项的可执行 JAR 中所述? , though that approach is not the only one to solve your problem. ,尽管这种方法不是解决您问题的唯一方法。

You need to build some kind of runtime image您需要构建某种运行时映像

There are numerous options for building runtime images and I don't know your requirements, so I can't recommend what you should do instead.构建运行时映像有很多选项,我不知道您的要求,所以我不能推荐您应该做什么。 Example options are:示例选项是:

  1. A zip/tar of your application plus libraries in a separate directory.应用程序的 zip/tar 以及单独目录中的库。
  2. The creation of a single jar that includes all dependant code.创建包含所有相关代码的单个 jar。
  3. Either of solutions 1 or 2, plus the inclusion of a packaged JRE.解决方案 1 或 2 中的任何一个,以及包含打包的 JRE。
  4. A runtime image with your code and libraries which also uses just the custom runtime portions of the JRE and JavaFX modules you need (using jlink).包含您的代码和库的运行时映像,它也仅使用您需要的 JRE 和 JavaFX 模块的自定义运行时部分(使用 jlink)。
  5. A native installer for either 3 or 4 (using jpackage + a native installer creation tool, eg WIX, RPM, DEB installer creators). 3 或 4 的本机安装程序(使用 jpackage + 本机安装程序创建工具,例如 WIX、RPM、DEB 安装程序创建者)。

The last method (native installer), is the packaging, distribution, and installation method I would recommend for most non-trivial applications.最后一种方法(本机安装程序)是我为大多数重要应用程序推荐的打包、分发和安装方法。

You need to research how to do this你需要研究如何做到这一点

To get your solution, you will need to do your own research, and, once you have chosen an approach and toolset, you could create a new question regarding the implementation of that approach, if you continue to have difficulties.要获得您的解决方案,您需要进行自己的研究,并且一旦您选择了一种方法和工具集,如果您仍然遇到困难,您可以创建一个关于该方法实施的新问题。

Related resources相关资源

Warning for shaded jars带阴影的罐子的警告

If you bundle all JavaFX code into a single jar using the maven shade plugin, you will get a warning like the following when you run your application from Java 16+:如果您使用 maven shade 插件将所有 JavaFX 代码捆绑到一个 jar 中,当您从 Java 16+ 运行应用程序时,您将收到如下警告:

WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @28c71909'

This indicates that such a configuration is not supported, and may (and probably will) break in future and perhaps current JavaFX platform revisions.这表明此类配置不受支持,并且可能(并且可能会)在未来和当前的 JavaFX 平台修订版中中断。 Thus, shaded jars that include JavaFX platform code are not recommended by me, even though such jars might currently work for your deployments.因此,我不推荐包含 JavaFX 平台代码的带阴影的 jar,即使此类 jar 目前可能适用于您的部署。

JavaFX 11+ is built to be used as a set of modules. JavaFX 11+ 被构建为用作一组模块。 Configurations are not supported if they do not run the JavaFX platform off of the module path but instead run the platform code off of the classpath (as a shaded jar would).如果配置不在模块路径之外运行 JavaFX 平台,而是在类路径之外运行平台代码(就像阴影 jar 那样),则不支持这些配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM