Java 无法在模块化 jar 文件中找到类,但 javap 可以

问题描述 投票:0回答:1

我有一个简单的 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 apache maven java-platform-module-system
1个回答
0
投票

使用

java
执行主类时,还必须从模块路径中声明正在使用哪些模块。

java --module-path jars --add-modules demoapp com.foo.bar.demoapp.App

jlink
的情况相同。

© www.soinside.com 2019 - 2024. All rights reserved.