当前位置: 首页 > 面试题库 >

Java类存在于类路径中,但启动失败并出现错误:找不到或加载主类

羊舌航
2023-03-14
问题内容

我有一个foobar.jar包含以下两个类的jar文件:

public class Foo {

    public static void main(String[] args) {
        System.out.println("Foo");
    }
}

另一个类如下所示:

import javax.batch.api.chunk.ItemProcessor;

public class Bar implements ItemProcessor {

    public static void main(String[] args) {
        System.out.println("Bar");
    }

    @Override
    public Object processItem(Object item) throws Exception {
        return item;
    }
}

如果我使用以下命令执行该程序,该程序将按预期方式运行并显示Foo

$ java -cp foobar.jar Foo
Foo
$

但是,如果我尝试使用类中的main方法来启动程序Bar,则JVM将显示启动错误并退出:

$ java -cp foobar.jar Bar
Error: Could not find or load main class Bar
$

这与我尝试使用不在jar中的类来尝试启动程序的错误相同,例如

$ java -cp foobar.jar BarNotThere
Error: Could not find or load main class BarNotThere
$

为什么会出现此错误?该Foo.main方法可以启动并且我能够Bar从jar中反编译该类的事实证明,该类应在类路径上可用。我意识到这可能与ItemProcessor不在classpath上的接口有关。但是java.lang.ClassNotFoundException在那种情况下我不应该得到吗?


问题答案:

问题确实是该接口ItemProcessor不在类路径上。请注意,错误状态为“ 查找加载 主类”。在BarNotThereJVM
的情况下,实际上是无法 找到 主类的。但是在这种Bar情况下,它无法 加载 主类。

为了完全加载一个类,JVM还需要每个超类对象的实例。在for
Bar的过程中,JVM尝试为加载类对象ItemProcessor。但是由于此接口不在类路径上,所以主类加载Bar失败,并且启动以终止Error: Could not find or load main class Bar

如果您在寻找有问题的类时遇到麻烦(因为没有消息这样说),则可以使用该jdeps工具检查类路径。只需使用相同的类路径,但运行jdeps而不是java

$ jdeps -cp foobar.jar Bar
foobar.jar -> java.base
foobar.jar -> not found
   <unnamed> (foobar.jar)
      -> java.io
      -> java.lang
      -> javax.batch.api.chunk                              not found

(这是使用openjdk-9创建的,实际输出可能会有所不同,具体取决于Java版本)

这应该为您提供足够的提示,以指示在哪里寻找缺失的班级。

进一步说明

注意加载和初始化类之间的区别。如果初始化期间类加载失败(这意味着该类已成功 找到加载
),您将获得期望的ClassNotFoundException。请参见以下示例:

import javax.batch.api.chunk.ItemProcessor;

public class FooBar {

    private static ItemProcessor i = new ItemProcessor() {
        @Override
        public Object processItem(Object item) throws Exception {
            return item;
        }
    };

    public static void main(String[] args) {
        System.out.println("Foo");
    }
}

在这种情况下,FooBar可以在启动期间加载该类。但是它无法初始化,因为静态字段i需要ItemProcessor类,而类不在类路径中。如果在类上执行了静态方法(在JVM尝试调用该main方法时就是这种情况),则初始化是前提条件。

$ java -cp foobar.jar FooBar
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/batch/api/chunk/ItemProcessor
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: javax.batch.api.chunk.ItemProcessor
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 7 more
$


 类似资料:
  • 这是我过去几天一直在处理的错误,不管我做了多少研究,它似乎对我没有任何帮助。 我知道它试图定位,我相信我已经将Eclipse配置为在(default packages)包中查找start.java,它就在那里。但是,我单击run按钮,错误就会不断弹出。请,我迫切需要帮助,任何意见将非常感谢。 [Update]我设法将start.class添加到我的类路径中,我只是尝试了StackExchange上

  • 我在Java中用-cp或-classpath标志编译时遇到了一个问题。下面我将试着解释一下这个问题: 比方说;我有两个文件-A.java和B.java.A.java有一个简单的公共类,有一个私有实例变量,一个get和一个set方法。B.java是A的驱动方法。它实例化A;为A的实例变量设置一些值,最后使用A中的get方法打印出该值。 我可以从命令行编译A.java和B.java。如果两个编译的类文

  • 问题内容: 我在编译和运行Java代码时遇到麻烦,目的是允许我将Java与模拟建模包Vensim的共享对象接口。 以下代码编译没有错误: 但是,当我尝试运行以下命令时: 我收到以下错误:“错误:找不到或加载主类SpatialModel”。我的SpatialModel.java代码确实包含一个“主要”方法(如下),所以我不确定是什么问题-有人可以帮我吗?谢谢。 问题答案: 你必须确保将文件的位置添加

  • 问题内容: 我在编译和运行Java代码时遇到了麻烦,该代码旨在允许我将Java与模拟建模包Vensim的共享对象接口。 以下代码编译没有错误: 但是,当我尝试运行以下命令时: 我收到以下错误:“错误:找不到或加载主类SpatialModel”。我的SpatialModel.java代码确实包含一个“主要”方法(如下),所以我不确定是什么问题- 有人可以帮我吗?谢谢。 问题答案: 您必须确保将文件的

  • 我一直在搜索这一点,但没有任何帮助,我试图运行的主要类,但不断得到一个错误。我负责这个 我的主文件位于中 我尝试了多个命令,但一无所获。 我想运行位于中的主类,但总是出现此错误,请提供帮助吗?