我有一个简单的 hello world,我正在尝试将其构建到模块化 jar 中以测试运行 jlink。我既无法运行 jar 文件,也无法使用 jlink 为其创建图像。
我在 Windows 上使用 Java 21。
这是项目中的java文件。
$ find src/main/java -name '*\.java'
src/main/java/com/foo/bar/demoapp/App.java
src/main/java/module-info.java
package com.foo.bar.demoapp;
public class App
{
public static void main( String[] args )
{
System.out.println("hello hello");
}
}
module demoapp {
exports com.foo.bar.demoapp;
}
我使用的是 Maven 3.9.6,我的 pom 文件非常简单。它指定
maven.compiler.(source|target)=21
。它将编译器插件版本设置为 3.13.0。它将jar插件设置为版本3.1.2,并指定App类为主类。
<configuration>
<archive>
<manifest>
<mainClass>com.foo.bar.demoapp.App</mainClass>
</manifest>
</archive>
</configuration>
我已验证该 jar 文件似乎包含预期的内容。
$ unzip -l jars/demo-app-1.0-SNAPSHOT.jar
Archive: jars/demo-app-1.0-SNAPSHOT.jar
Length Date Time Name
--------- ---------- ----- ----
116 2024-04-08 12:30 META-INF/MANIFEST.MF
552 2024-04-08 12:30 com/foo/bar/demoapp/App.class
5160 2024-04-08 12:09 META-INF/maven/com.foo.bar/demo-app/pom.xml
64 2024-04-08 12:30 META-INF/maven/com.foo.bar/demo-app/pom.properties
283 2024-04-08 12:30 module-info.class
我使用
javap
来验证 module-info 类是否按要求显示主类。
$ javap -verbose --module demoapp --module-path jars module-info
Classfile jar:file:///C:/Users/wrobert1/dev/foo/demo-app/jars/demo-app-1.0-SNAPSHOT.jar!/module-info.class
Last modified Apr 8, 2024; size 283 bytes
SHA-256 checksum 004814b6bbe32c09ecba1fe2a02289d5e4b33a14426856ca6598e1c256405443
Compiled from "module-info.java"
module [email protected]
minor version: 0
major version: 65
flags: (0x8000) ACC_MODULE
this_class: #1 // "module-info"
super_class: #0
interfaces: 0, fields: 0, methods: 0, attributes: 4
... constant pool elided ...
SourceFile: "module-info.java"
Module:
#6,0 // demoapp
#8 // 1.0-SNAPSHOT
1 // requires
#9,8000 // "java.base" ACC_MANDATED
#11 // 21.0.1
1 // exports
#12,0 // com/foo/bar/demoapp
0 // opens
0 // uses
0 // provides
ModuleMainClass: #16 // com.foo.bar.demoapp.App
ModulePackages:
#12 // com.foo.bar.demoapp
我还用
javap
来验证App.class有一个main函数
$ javap --module demoapp --module-path jars com.foo.bar.demoapp.App
Compiled from "App.java"
public class com.foo.bar.demoapp.App {
public com.foo.bar.demoapp.App();
public static void main(java.lang.String[]);
}
鉴于所有这些,当我尝试运行 jar 文件时,我收到 ClassNotFoundException。
$ java --module-path jars com.foo.bar.demoapp.App
Error: Could not find or load main class com.foo.bar.demoapp.App
Caused by: java.lang.ClassNotFoundException: com.foo.bar.demoapp.App
并且
jlink
可能由于相同的原因而失败。
$ jlink --module-path jars --output linked --add-modules=java.base --launcher startmeup=demoapp/com.foo.bar.demoapp.App
Error: java.lang.IllegalArgumentException: demoapp does not have main class: com.dhl.raf.demoapp.App
我已经寻找可能是什么问题很长一段时间了,但没有运气。我不确定我在这里做错了什么。
使用
java
执行主类时,还必须从模块路径中声明正在使用哪些模块。
java --module-path jars --add-modules demoapp com.foo.bar.demoapp.App
与
jlink
的情况相同。