当前位置: 首页 > 知识库问答 >
问题:

jdeps在fat jar中使用Java 11和JavaFX时失败

浦泳
2023-03-14

我试图使用jdeps(和jlink)部署我的Java 11应用程序,它使用JavaFX11。在我的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 chaincoder,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

module-info.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>

共有1个答案

衡翰翮
2023-03-14

您为什么要使用maven-dependency-plugin插件?

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

猜猜不同JavaFX模块的module-info.class文件会发生什么?只有一个占上风,在本例中是javafx.media中的一个。

所以您已经在目标/类中创建了一个新模块!

它名为JavaFX.media,包含您的项目类和所有JavaFX类,其中包括来自JavaFX.baseJavaFX.graphics的所有内容。

如果选中此目标/类/module-info.class文件:

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

这个“模块”已经包含了所有JavaFX类,它还需要JavaFX.baseJavaFX.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插件?如果你不需要它就把它取下来。

    您将包含所有JavaFX类的target文件夹添加到module-path:

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

    显然这是错误的,因为文件夹包含所有JavaFX类和一个错误的module-info描述符。它不是一个有效的模块,所以只需将它从module-path中删除。

    • 则不需要将JDK路径添加到module-path中,这是默认情况下的操作。

    所以你可以有:

    jdeps --list-deps --module-path /Users/…/javafx-sdk-11.0.2/lib
    
    • 那么,在添加模块时,不需要添加javafx.basejavafx.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>
    

  •  类似资料:
    • 问题内容: 我已使用内置的Gradle支持在IntelliJ(2019.2)中设置了OpenJDK 12项目。为了设计使用JavaFX 12的GUI,我已经阅读并阅读了多次安装指南,在IDE中运行程序没有问题,问题是当我尝试构建要运行的发行版的.jar文件时陷入问题。到目前为止,我还没有找到一个可行的解决方案,而我搜索了很多QUITE,几乎为此扯掉了头发。当前,当我尝试使用java -jar“ j

    • 我试着把我的主类移到一个不扩展Application的单独的类中,这就是导致上述错误的原因。如果不移动我的主类,我会得到一个不同的错误。 My Build.Gradle当前看起来如下所示: 如果我让我的main方法扩展应用程序,那么我会得到一个错误,说明找不到我的main类,尽管我可以看到它存在于生成的.jar文件中。 编辑 我试过指南的模块化部分。这样做,我有超过100个错误时,试图建立。它们都

    • 我在这里下载了最新的JavaFX版本。我已经将它解压缩到包含其他JDK的Java文件夹中,但我真的不知道该怎么办。我读过一些描述如何使用Maven或Gradle连接项目的长篇指南,但我从未使用过这些。有没有办法在IntelliJ菜单中添加JavaFX支持?

    • 我遵循了https://blog.jetbrains.com/idea/2013/03/packaging-javafx-2-applications-in-intellij-idea-121/中的步骤 但是当我尝试构建工件时,在最后一步中,我得到了这个错误 错误:Java FX Packager:无法生成工件-FX:Deploy在此JDK中不可用 这里有一个快速测试的hello world应用程

    • 当Java11排除了JavaFX作为最新版本的一部分时,我得到了以下错误。 那么如何在Java11中将JavaFX添加到Eclipse中呢?谢了。

    • 我试图在使用OpenJFX的项目上运行jdeps命令,但一直失败。 我正在使用的命令尽可能简化: javafx-jmods-11.0。2是包含OpenJFX jmod文件的目录。 当我运行此命令时,会出现以下错误: 有人有什么想法或建议为什么它找不到位于Y:\javafx-jmods-11.0.2中的javafx.base模块吗?