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 をその上にコピー) して、欠落または破損したクラスをシミュレートします。何が起こるかは次のとおりです。
最初の試行 new 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(ネイティブメソッド)で
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 (クラスが見つからない場合にクラス ローダーによってスローされる) が発生します。この例外は、未チェックの NoClassDefFoundError でラップする必要がありますnew b()
。
もちろん、2 回目の試行も失敗しますが、ClassLoader は失敗したクラス ローダーを記憶しているように見えるため、ラップされた例外はもうありません。実際に何が起こったのかまったく手がかりがなく、NCDFE だけが表示されます。
そのため、根本原因のない NCDFE が表示された場合は、エラーの原因を見つけるために、クラスが最初にロードされた時点までさかのぼって追跡できるかどうかを確認する必要があります。