多模块JavaFX maven项目打包问题

Dan*_*kov 3 java javafx intellij-idea maven multi-module

这是使用 Maven 创建多模块 JavaFX 应用程序的尝试。

鉴于该项目的结构如下:

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

按照上述方案的顺序,我们有以下 pom 文件结构:

pom1.xml

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

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">
    <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>
Run Code Online (Sandbox Code Playgroud)

pom3.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>
Run Code Online (Sandbox Code Playgroud)

为了让 UI 能够访问 WordGenerator 逻辑,我们尝试构建应用程序的方法是package对 pom1.xml 指令的结果进行 Maven 处理

正如前面提到的,我们得到了上述错误:

Error: Could not find or load main class org.games.marty.App
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
Run Code Online (Sandbox Code Playgroud)

据我的理解,JavaFX 依赖项是通过 maven 安装的,应该可用,但它们丢失了?

jew*_*sea 6

mvn package使用包装maven-jar-plugin是不够的

mvn package默认情况下,只是为您的应用程序代码打包 jar,它不会包含所有依赖库代码(这就是为什么当您尝试运行应用程序时找不到依赖代码)。

您可以使用程序集打包应用程序代码和依赖库,详细信息请参阅如何使用 Maven 创建具有依赖项的可执行 JAR?,尽管这种方法并不是解决您的问题的唯一方法。

您需要构建某种运行时映像

构建运行时映像有很多选项,但我不知道您的要求,因此我无法推荐您应该做什么。示例选项有:

  1. 应用程序的 zip/tar 以及单独目录中的库。
  2. 创建包含所有相关代码的单个 jar。
  3. 解决方案 1 或 2 之一,加上打包的 JRE。
  4. 包含代码和库的运行时映像,它还仅使用您需要的 JRE 和 JavaFX 模块的自定义运行时部分(使用 jlink)。
  5. 适用于 3 或 4 的本机安装程序(使用 jpackage + 本机安装程序创建工具,例如 WIX、RPM、DEB 安装程序创建者)。

最后一种方法(本机安装程序)是我为大多数重要应用程序推荐的打包、分发和安装方法。

你需要研究如何做到这一点

为了获得解决方案,您需要进行自己的研究,并且一旦您选择了一种方法和工具集,如果您仍然遇到困难,您可以创建一个有关该方法实施的新问题。

相关资源

阴影罐子警告

如果您使用 Maven Shade 插件将所有 JavaFX 代码捆绑到一个 jar 中,那么当您从 Java 16+ 运行应用程序时,您将收到如下警告:

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

这表明这样的配置不受支持,并且可能(并且可能会)在未来以及当前的 JavaFX 平台修订版中中断。因此,我不推荐包含 JavaFX 平台代码的阴影 jar,即使此类 jar 目前可能适用于您的部署。

JavaFX 11+ 旨在用作一组模块。如果配置不从模块路径运行 JavaFX 平台,而是从类路径运行平台代码(就像阴影 jar 那样),则不支持配置。