Ein NoClassDefFoundError (NCDFE) tritt auf, wenn Ihr Code "new Y()" ausführt und die Klasse Y nicht finden kann.
Es kann einfach sein, dass Y in Ihrem Classloader fehlt, wie die anderen Kommentare andeuten, aber es könnte auch sein, dass die Klasse Y nicht signiert ist oder eine ungültige Signatur hat, oder dass Y von einem anderen Classloader geladen wird, der für Ihren Code nicht sichtbar ist, oder sogar, dass Y von Z abhängt, das aus einem der oben genannten Gründe nicht geladen werden konnte.
In diesem Fall merkt sich die JVM das Ergebnis des Ladens von X (NCDFE) und wirft jedes Mal, wenn Sie nach Y fragen, einfach einen neuen NCDFE, ohne Ihnen zu sagen, warum:
class a {
static class b {}
public static void main(String args\[\]) {
System.out.println("First attempt new b():");
try {new b(); } catch(Throwable t) {t.printStackTrace();}
System.out.println("\\nSecond attempt new b():");
try {new b(); } catch(Throwable t) {t.printStackTrace();}
}
}
Speichern Sie dies als a.java irgendwo
Der Code versucht einfach, eine neue "b"-Klasse zweimal zu instanziieren, ansonsten hat er keine Bugs und tut nichts.
Kompilieren Sie den Code mit javac a.java
Dann führen Sie a durch Aufruf von java -cp . a
-- es sollten nur zwei Zeilen Text ausgedruckt werden, und es sollte ohne Fehler laufen.
Löschen Sie dann die Datei "a$b.class" (oder füllen Sie sie mit Müll, oder kopieren Sie a.class darüber), um die fehlende oder beschädigte Klasse zu simulieren. Das passiert folgendermaßen:
First attempt new b():
java.lang.NoClassDefFoundError: a$b
at a.main(a.java:5)
Caused by: java.lang.ClassNotFoundException: a$b
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 1 more
Second attempt new b():
java.lang.NoClassDefFoundError: a$b
at a.main(a.java:7)
Der erste Aufruf führt zu einer ClassNotFoundException (die vom Klassenlader ausgelöst wird, wenn er die Klasse nicht finden kann), die in einen ungeprüften NoClassDefFoundError verpackt werden muss, da der betreffende Code ( new b()
) sollte einfach funktionieren.
Der zweite Versuch wird natürlich auch fehlschlagen, aber wie Sie sehen können, ist die gewickelte Ausnahme nicht mehr vorhanden, da der ClassLoader sich anscheinend an fehlgeschlagene Klassenlader erinnert. Sie sehen nur die NCDFE mit absolut keinem Hinweis darauf, was wirklich passiert ist.
Wenn Sie also jemals einen NCDFE ohne Ursache sehen, müssen Sie sehen, ob Sie die Ursache des Fehlers bis zum ersten Laden der Klasse zurückverfolgen können.