Java类存在于类路径中,但启动失败并出现错误:找不到或加载主类
我有一个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 FooFoo
$
但是,如果我尝试使用类中的main方法来启动程序Bar
,则JVM将显示启动错误并退出:
$ java -cp foobar.jar BarError: Could not find or load main class Bar
$
这与我尝试使用不在jar中的类来尝试启动程序的错误相同,例如
$ java -cp foobar.jar BarNotThereError: Could not find or load main class BarNotThere
$
为什么会出现此错误?该Foo.main
方法可以启动并且我能够Bar
从jar中反编译该类的事实证明,该类应在类路径上可用。我意识到这可能与ItemProcessor
不在classpath上的接口有关。但是java.lang.ClassNotFoundException
在那种情况下我不应该得到吗?
回答:
问题确实是该接口ItemProcessor
不在类路径上。请注意,错误状态为“ 或 主类”。在BarNotThere
JVM
的情况下,实际上是无法 主类的。但是在这种Bar
情况下,它无法 主类。
为了完全加载一个类,JVM还需要每个超类对象的实例。在for
Bar
的过程中,JVM尝试为加载类对象ItemProcessor
。但是由于此接口不在类路径上,所以主类加载Bar
失败,并且启动以终止Error:
Could not find or load main class Bar。
如果您在寻找有问题的类时遇到麻烦(因为没有消息这样说),则可以使用该jdeps
工具检查类路径。只需使用相同的类路径,但运行jdeps
而不是java
:
$ jdeps -cp foobar.jar Barfoobar.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 FooBarError: 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
$
以上是 Java类存在于类路径中,但启动失败并出现错误:找不到或加载主类 的全部内容, 来源链接: utcz.com/qa/423918.html