我正在尝试使用jdeps(和jlink)来部署使用JavaFX 11的Java 11应用程序。在Java IDE内都能正常运行。但是,当我使用jdep时,出现以下错误,这表明找不到某些模块或软件包。我被困住了。感谢您的帮助。
jdeps --list-deps-模块路径 /用户/…/目标:/库/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home/jmods:/用户/.../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>
答案 0 :(得分:1)
您为什么使用maven-dependency-plugin
插件?
如果您看到unpack-dependencies
目标的目的,您会注意到target/classes
文件夹包含90 MB以上的类,在插件提取了所有项目依赖项(包括JavaFX依赖项)之后,并将它们全部结合起来。
并猜想对于每个不同的JavaFX模块,不同的module-info.class
文件会发生什么?只有一种优势,在这种情况下,就是javafx.media
中的一种。
因此,您已经在target/classes
中创建了一个新模块!
它名为javafx.media
,包含您的项目类和所有 JavaFX类,其中包括javafx.base
或javafx.graphics
中的所有类。
如果您检查此target/classes/module-info.class
文件:
module javafx.media {
requires transitive javafx.base;
requires transitive javafx.graphics;
...
}
已经包含所有JavaFX类的“模块”还将再次要求 来自javafx.base
和javafx.graphics
的那些类,并将它们复制。
这说明了您的错误消息:
Error: Module javafx.media contains package javafx.collections,
module javafx.base exports package javafx.collections to javafx.media
现在,您可以看到您的 new 模块javafx.media
包含许多软件包,这些软件包也从javafx.base
导出到该软件包,并且违反了split package not allowed条件:
同一Java包只能在运行时由单个Java模块导出。换句话说,您不能有两个(或更多)模块同时导出使用中的同一软件包。如果您这样做,Java VM将在启动时抱怨。
可能的解决方案
也许您根本不需要maven-dependency-plugin
插件?如果不需要,请将其删除。
您正在将target
文件夹和所有JavaFX类添加到模块路径:
jdeps --list-deps --module-path /Users/…/target:...
显然这是错误的,因为classes
文件夹包含所有JavaFX类和错误的模块信息描述符。这不是有效的模块,因此只需将其从module-path中删除。
所以您可以拥有:
jdeps --list-deps --module-path /Users/…/javafx-sdk-11.0.2/lib
javafx.base
或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>