JPMS/Jigsaw 模块中缺少主要 Class

JPMS/Jigsaw Missing Main Class in Module

我正在尝试创建一个模块化的可执行 jar 文件,它可以是 运行 with java -p <jar file> -m <module> on Java 9.0.1.

这在使用 jar cfe test.jar test.Main -C classes/ . 创建 jar 时按预期工作,但在使用 mvn packagemvn assembly:single.

生成时抛出 module test does not have a MainClass attribute, use -m <module>/<main-class>

这些 maven 生成的 jar 仍然适用于 java -p test.jar -m test/test.Main,并且所有 jar 都适用于 java -jar test.jar 的类路径。


我用 jar xf test.jar 检查了 jar 内容,发现这些 jar 完全一样,除了清单(见下文):

Manifest-Version: 1.0
Created-By: 9.0.1 (Oracle Corporation)
Main-Class: test.Main

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: testuser
Build-Jdk: 9.0.1
Main-Class: test.Main

值得注意的是,在指定工作清单时仍然不能使用 java -p test.jar -m test

$ jar cfm test.jar test-contents/META-INF/MANIFEST.MF -C classes/ .
$ java -p test.jar -m test

module test does not have a MainClass attribute, use -m <module>/<main-class>

编辑:具有预期行为的回购:https://github.com/deontologic/test

虽然我在 jar tool documentation precisely either, yet the jmod tool 中找不到更好的定义。

--main-class class-name 

Specifies main class to record in the module-info.class file.

我可以进一步查看 JDK 代码,您执行不同命令时的行为似乎与 ModuleDescriptor.mainClass()mainClass 属性有关。

因为在用 --main-class 标志打包 jar 时,应该使模块描述符中的条目执行模块,而无需在执行期间指定 main class 的完全限定名称。

另一方面,这不是真的 using the maven jar creation 并且可能会在您发现的未来升级中得到修复。


更多关于以下为什么有效的信息:

java -jar test-1.0.0-SNAPSHOT-jar-with-dependencies.jar

如果指定了 -jar 选项,那么它的参数是包含应用程序的 class 和资源文件的 JAR 文件的名称。启动 class 必须由其清单文件中的 Main-Class 清单 header 指示 (META-INF/MANIFEST.MF)

很明显,为什么指定完全限定名称的工作方式如下:

java -p target/test-1.0.0-SNAPSHOT-jar-with-dependencies.jar -m test/test.Main