3

我正在尝试使用 jdeps(和 jlink)来部署使用 JavaFX 11 的 Java 11 应用程序。在我的 Java IDE 中运行良好。但是当我使用 jdep 时,我得到以下错误,这表明找不到某些模块或包。我被困住了。谢谢你的帮助。

jdeps --list-deps --module-path /Users/…/target:/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home/jmods:/Users/…/javafx-sdk-11.0。 2/lib --add-modules 链编码器、javafx.fxml、javafx.base、javafx.controls、javafx.graphics、javafx.web /Users/…/target/chaincoder4-1.0.jar

Error: Module javafx.media contains package javafx.collections, module javafx.base exports package javafx.collections to javafx.media

模块信息.java 是

模块链编码器{

requires   javafx.web;
requires   javafx.graphics;
requires   javafx.controls;
requires   javafx.fxml;
requires   javafx.base;
requires   javafx.media;

requires java.desktop;
requires java.base;
requires java.xml;
requires java.logging;

requires jdk.jsobject;

exports   core;

}

pom.xml 是

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>11.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-base</artifactId>
            <version>11.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>11.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-web</artifactId>
            <version>11.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11.0.2</version>
        </dependency>


<build>
    <plugins>

        <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>core.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                    <configuration>
                        <excludeScope>system</excludeScope>
                        <excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>11</source>
                <target>11</target>
                <compilerArguments>
                    <bootclasspath>${sun.boot.class.path}${path.separator}${java.home}/lib/jfxrt.jar</bootclasspath>
                </compilerArguments>
            </configuration>
        </plugin> 
    </plugins>

</build>
4

1 回答 1

1

maven-dependency-plugin您使用该插件的任何原因?

如果您看到unpack-dependencies目标在做什么,您会注意到这些target/classes文件夹包含超过 90 MB 的类,在插件提取所有项目依赖项(包括 JavaFX 依赖项)并将它们组合起来之后。

猜猜module-info.class每个不同 JavaFX 模块的不同文件会发生什么?只有一个占上风,在这种情况下,来自javafx.media.

所以你已经创建了一个新模块target/classes

它被命名为javafx.media,包含您的项目类和所有JavaFX 类,其中包括所有来自javafx.basejavafx.graphics

如果您检查此target/classes/module-info.class文件:

module javafx.media {
    requires transitive javafx.base;
    requires transitive javafx.graphics;
    ...
}

这个已经包含所有 JavaFX 类的“模块”也将再次javafx.base需要来自and的那些类,并javafx.graphics复制它们。

这解释了您的错误消息:

Error: Module javafx.media contains package javafx.collections, 
       module javafx.base exports package javafx.collections to javafx.media

现在您可以看到您的模块javafx.media包含许多也从中导出的包,javafx.base这违反了不允许拆分包的条件:

同一个 Java 包只能由单个 Java 模块在运行时导出。换句话说,您不能有两个(或更多)模块同时导出使用中的同一个包。如果你这样做,Java VM 会在启动时抱怨。

可能的解决方案

  • 也许您根本不需要maven-dependency-plugin插件?如果您不需要它,请将其删除。

  • 您正在将target包含所有 JavaFX 类的文件夹添加到模块路径:

    jdeps --list-deps --module-path /Users/…/target:...
    

显然这是错误的,因为该classes文件夹包含所有 JavaFX 类和错误的模块信息描述符。它不是一个有效的模块,所以只需从模块路径中删除它。

  • 然后您不需要将 JDK 路径添加到模块路径,这是默认完成的。

所以你可以有:

jdeps --list-deps --module-path /Users/…/javafx-sdk-11.0.2/lib
  • 然后,当您添加模块时,您不需要添加javafx.baseor javafx.graphics,因为它们包含在传递依赖项中(这也适用于您的 pom 中列出的依赖项)。参见例如javafx.web

所以你将拥有:

jdeps --list-deps --module-path /Users/…/javafx-sdk-11.0.2/lib
    -add-modules chaincoder,javafx.fxml,javafx.web
  • 但是请注意,您有一个名为 的模块chaincoder,它已经包含了所有需要的模块,因此您可以只拥有这个:

    jdeps --list-deps --module-path /Users/…/javafx-sdk-11.0.2/lib
        -add-modules chaincoder /Users/…/target/chaincoder4-1.0.jar
    

那应该行得通。

最后一点,您可以jfxrt.jar从编译器插件中删除:

<configuration>
    <source>11</source>
    <target>11</target>
    <compilerArguments>
            <bootclasspath>${sun.boot.class.path}${path.separator}${java.home}/lib/jfxrt.jar</bootclasspath>
    </compilerArguments>
</configuration>

因为它已经不存在了。您拥有包含在依赖项中的所有 JavaFX 类:

<configuration>
    <source>11</source>
    <target>11</target>
</configuration>
于 2019-02-18T09:30:47.623 回答