NoClassDefFoundError (NCDFE) ma miejsce, gdy kod uruchamia „new Y ()” i nie może znaleźć klasy Y.
Być może po prostu brakuje Y w module ładującym klasy, jak sugerują inne komentarze, ale może być tak, że klasa Y nie jest podpisana lub ma nieprawidłowy podpis, lub że Y jest ładowany przez inny moduł ładujący klasy niewidoczny dla Twojego kodu lub nawet, że Y zależy od Z, którego nie można załadować z żadnego z powyższych powodów.
Jeśli tak się stanie, wówczas JVM zapamięta wynik ładowania X (NCDFE) i po prostu wyrzuci nowy NCDFE za każdym razem, gdy poprosisz o Y, bez podania przyczyny:
klasa A {
klasa statyczna b {}
public static void main (String args []) {
System.out.println („Pierwsza próba nowa b ():”);
spróbuj {new b (); } catch (Throwable t) {t.printStackTrace ();}
System.out.println ("\ n Druga próba nowa b ():");
spróbuj {new b (); } catch (Throwable t) {t.printStackTrace ();}
}
}
zapisz gdzieś jako a.java
Kod po prostu próbuje dwa razy utworzyć nową klasę „b”, poza tym nie ma żadnych błędów i nic nie robi.
Skompiluj kod javac a.java
, a następnie uruchom a, wywołując java -cp . a
- powinien po prostu wydrukować dwa wiersze tekstu i powinien działać poprawnie bez błędów.
Następnie usuń plik „a $ b.class” (lub wypełnij go śmieciami lub skopiuj nad nim klasę a.class), aby zasymulować brakującą lub uszkodzoną klasę. Oto co się dzieje:
Pierwsza próba nowa b ():
java.lang.NoClassDefFoundError: a $ b
o godz. (a.java:5)
Przyczyna: java.lang.ClassNotFoundException: a $ b
na java.net.URLClassLoader $ 1.run (URLClassLoader.java:200)
at java.security.AccessController.doPrivileged (metoda rodzima)
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)
... jeszcze 1
Druga próba nowa b ():
java.lang.NoClassDefFoundError: a $ b
o godz. (a.java:7)
Pierwsze wywołanie powoduje wyjątek ClassNotFoundException (generowany przez moduł ładujący klasy, gdy nie może znaleźć klasy), który musi być zawinięty w niezaznaczone NoClassDefFoundError, ponieważ kod, o którym mowa ( new b()
) powinien po prostu działać.
Druga próba oczywiście również się nie powiedzie, ale jak widać zawinięty wyjątek już nie istnieje, ponieważ ClassLoader wydaje się pamiętać, że nie udało się załadować klas. Widzisz tylko NCDFE bez absolutnie żadnego pojęcia, co tak naprawdę się wydarzyło.
Więc jeśli kiedykolwiek zobaczysz NCDFE bez podstawowej przyczyny, musisz sprawdzić, czy możesz prześledzić do pierwszego załadowania klasy, aby znaleźć przyczynę błędu.
-verbose
(np.-verbose:class -verbose:jni
) Pomaga - ale mogsie informuje poniżej ich odpowiedź, że nie zapewnia to żadnych dodatkowych użytecznych informacji :(