问题确实是该接口
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 Barfoobar.jar -> java.basefoobar.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 againException 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$



