11

我正在尝试创建一个可以java -p <jar file> -m <module>在 Java 9.0.1 上运行的模块化可执行 jar 文件。

这在使用 创建 jar 时按预期工作,但在使用and生成时jar cfe test.jar test.Main -C classes/ .会抛出。module test does not have a MainClass attribute, use -m <module>/<main-class>mvn packagemvn assembly:single

这些 maven 生成的 jar 仍然可以java -p test.jar -m test/test.Main使用java -jar test.jar.


我检查了 jar 内容jar xf test.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

4

1 回答 1

6

虽然我也无法在jar工具文档中准确找到这一点,但该jmod工具对它的定义要好一些。

--main-class class-name 

指定要记录在 module-info.class 文件中的主类。

我可以进一步查看 JDK 代码,执行不同命令时的行为似乎mainClassModuleDescriptor.mainClass().

由于在打包带有--main-classflag的jar时,应该使模块描述符中的条目执行模块,而无需在执行过程中指定主类的完全限定名。

另一方面,使用 maven jar 创建是不正确的,并且可能会在您发现的未来升级中得到修复。


更多关于为什么以下工作:

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

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

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

java -p target/test-1.0.0-SNAPSHOT-jar-with-dependencies.jar -m test/test.Main
于 2017-12-19T03:47:39.183 回答