NoClassDefFoundError(NCDFE)は、コードが "new Y()"を実行し、Yクラスが見つからない場合に発生します。
他のコメントが示唆するように、クラスローダーからYが欠落している可能性がありますが、Yクラスが署名されていないか、無効な署名があるか、またはYがコードから見えない別のクラスローダーによって読み込まれている可能性があります、またはそのYはZに依存し、上記の理由のいずれかのためにロードできませんでした。
これが発生すると、JVMはX(NCDFE)をロードした結果を記憶し、理由を告げることなく、Yを要求するたびに新しいNCDFEをスローします。
クラスa {
静的クラスb {}
public static void main(String args []){
System.out.println( "最初の試行new b():");
{new b();を試してください } catch(Throwable t){t.printStackTrace();}
System.out.println( "\ n2回目の試行new b():");
{new b();を試してください } catch(Throwable t){t.printStackTrace();}
}
}
これをa.javaとしてどこかに保存します
このコードは、新しい "b"クラスを2回インスタンス化しようとするだけです。それ以外は、バグがなく、何もしません。
でコードをコンパイルしjavac a.java
、次に呼び出しによってaを実行しjava -cp . a
ます。2行のテキストを出力するだけで、エラーなしで正常に実行されます。
次に、「a $ b.class」ファイルを削除して(またはゴミで埋めるか、a.classをその上にコピーして)、欠落または破損したクラスをシミュレートします。ここで何が起こるかです:
最初に新しいb()を試みます。
java.lang.NoClassDefFoundError:a $ b
a.main(a.java:5)で
原因:java.lang.ClassNotFoundException:a $ b
java.net.URLClassLoader $ 1.run(URLClassLoader.java:200)で
java.security.AccessController.doPrivileged(Native Method)で
java.net.URLClassLoader.findClass(URLClassLoader.java:188)で
java.lang.ClassLoader.loadClass(ClassLoader.java:307)で
sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:301)で
java.lang.ClassLoader.loadClass(ClassLoader.java:252)で
java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... あともう1つ
2回目の試行new b():
java.lang.NoClassDefFoundError:a $ b
a.main(a.java:7)で
最初の呼び出しの結果、ClassNotFoundExceptionが発生し(クラスが見つからないときにクラスローダーによってスローされます)、問題のコード(new b()
)が機能するため、チェックされていないNoClassDefFoundErrorにラップする必要があります。
もちろん、2回目の試行も失敗しますが、ClassLoaderが失敗したクラスローダーを記憶しているように見えるため、ラップされた例外はもうありません。NCDFEのみが表示され、実際に何が起こったのかまったくわかりません。
したがって、根本原因のないNCDFEが表示された場合は、クラスが最初にロードされた時刻に戻ってエラーの原因を見つけることができるかどうかを確認する必要があります。
-verbose
(例-verbose:class -verbose:jni
:)で実行すると役立つことがよくあります—しかし、モグジーは回答の下に、これが追加の有用な情報を提供しないと報告しています:(