【问题标题】:JPMS/Jigsaw Missing Main Class in ModuleJPMS/Jigsaw 模块中缺少主类
【发布时间】:2018-06-01 09:35:47
【问题描述】:

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

这在使用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内容,发现jars完全一样,除了manifests(见下文):

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

【问题讨论】:

  • 我使用的是最新的 (3.1.0) 程序集插件,但我不认为它是特定于 maven 的。通过jar指定主类时,我似乎只能创建一个可执行jar
  • 如果不手动指定主类,我将无法执行 jar,除非使用 jar 的 --main-class 属性。
  • @nullpointer 我添加了一个 repo,希望自述文件能阐明预期的行为。
  • 是的,它们是不同的! maven 缺少 ModuleMainClass 说明符。未解决的问题在这里:issues.apache.org/jira/browse/MJAR-238 感谢您的帮助!
  • 主要要了解JAR清单中的Main-Class属性是针对可执行JAR(java -jar)的,它与module-info.class中的ModuleMainClass类文件属性不是一回事.当您使用 --main-class 或 -e 选项时,jar 工具会同时设置。当清单文件包含 Main-Class 属性时,jar --manifest-file 或 -m 选项不会添加或更新 ModuleMainClass 类文件属性。

标签: java maven executable-jar java-9 module-info


【解决方案1】:

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

--main-class class-name 

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

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

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

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


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2018-02-16
    • 2021-10-14
    • 1970-01-01
    • 2021-01-12
    • 2022-01-18
    相关资源
    最近更新 更多