Fehler "NoClassDefFoundError: Klasse konnte nicht initialisiert werden"

77

Wenn ich mein Projekt ausführe, erhalte ich zahlreiche Ausgaben dieses Fehlers:

9. September 2009 08:22:23 org.apache.catalina.core.StandardWrapperValve wird aufgerufen
SEVERE: Servlet.service () für Servlet Jersey hat eine Ausnahme ausgelöst
java.lang.NoClassDefFoundError: Klasse SpringFactory konnte nicht initialisiert werden
        at com.point2.prospect.persistence.hibernate.HibernateTransactionInterceptor.doFilter (HibernateTrans
actionInterceptor.java:17)
        unter org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:235)
        unter org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206)
        at com.point2.prospect.restapi.ServerErrorInterceptor.doFilter (ServerErrorInterceptor.java:27)
        unter org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:235)
        unter org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206)
        unter org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:191)
        unter org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:109)
        unter org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11Processor.process (Http11Processor.java:845)
        at org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process (Http11Protocol.java:583)
        unter org.apache.tomcat.util.net.JIoEndpoint $ Worker.run (JIoEndpoint.java:447)
        bei java.lang.Thread.run (Thread.java:619)

Ich stelle fest, dass dieses Problem im gesamten Web gefragt wird, aber keine wirklichen Antworten enthält. Was ist eine allgemeine Ursache für diese Art von Fehler?

Michael Wiles
quelle

Antworten:

204

Der NoClassDefFound-Fehler ist ein nebulöser Fehler und verbirgt häufig ein schwerwiegenderes Problem. Es ist nicht dasselbe wie ClassNotFoundException (die ausgelöst wird, wenn die Klasse einfach nicht vorhanden ist).

NoClassDefFound gibt möglicherweise an, dass die Klasse nicht vorhanden ist, wie die Javadocs angeben. Sie wird jedoch normalerweise ausgelöst, wenn der Klassenladeprogramm die Bytes für die Klasse geladen und "defineClass" darauf aufgerufen hat. Überprüfen Sie auch Ihre vollständige Stapelverfolgung sorgfältig auf andere Hinweise oder mögliche "Ursache" -Ausnahmen (obwohl Ihre spezielle Rückverfolgung keine anzeigt).

Der erste Ort, an dem Sie nachsehen müssen, wenn Sie einen NoClassDefFoundError erhalten, sind die statischen Bits Ihrer Klasse, dh alle Initialisierungen, die während der Definition der Klasse stattfinden. Wenn dies fehlschlägt, wird ein NoClassDefFoundError ausgelöst - es soll einen ExceptionInInitializerError auslösen und die Details des Problems angeben, aber meiner Erfahrung nach sind diese selten. Der ExceptionInInitializerError wird nur ausgeführt, wenn er zum ersten Mal versucht, die Klasse zu definieren. Danach wird nur noch NoClassDefFound ausgelöst. Schauen Sie sich also frühere Protokolle an.

Ich würde daher vorschlagen, den Code in dieser HibernateTransactionInterceptor-Zeile zu betrachten und zu sehen, was er benötigt. Es scheint, dass die Klasse SpringFactory nicht definiert werden kann. Überprüfen Sie also möglicherweise den Initialisierungscode in dieser Klasse, der möglicherweise hilfreich ist. Wenn Sie es debuggen können, stoppen Sie es in der letzten Zeile über (17) und debuggen Sie in, damit Sie versuchen können, die genaue Zeile zu finden, die die Ausnahme verursacht. Überprüfen Sie auch weiter oben im Protokoll, ob Sie möglicherweise Glück haben, dass ein ExceptionInInitializerError vorliegt.

Michael Wiles
quelle
22
Vielen Dank. Wenn ich mich statischen Initialisierungsblöcken zuwandte, ersparte ich mir stundenlange Ärger.
Boris Brudnoy
1
"dh jede Initilisierung, die während der Definition der Klasse stattfindet" - Danke!
Matt MacLean
2
Eine weitere gute Idee ist es, Ihr Protokoll an eine Datei weiterzuleiten und nach java.lang.ClassNotFoundException zu suchen. Möglicherweise gibt es eine davon, die Ihnen sagt, welche Klasse, die geladen werden soll, alle NoClassDefFoundError-Ausnahmen erzeugt hat. Hat für mich gearbeitet.
Ryan Shillington
Und noch etwas hinzuzufügen ... Ich habe auch festgestellt, dass Sie einen NoClassDefFoundError erhalten, wenn eine Klasse keine benötigte Klasse findet. Sie erhalten also eine Ausnahme für die Klasse, die nicht gefunden wurde, für die Klasse, die nicht gefunden werden kann, und einen NoClassDefFoundError für die zu definierende Klasse.
Michael Wiles
1
Der Grund dafür ist, dass der statische Initialisierer nur einmal ausgeführt wird ... diese Regel wird konsistent beibehalten. Wenn es also einmal ausgeführt wird und fehlschlägt, wird der ExceptionInInitializer-Fehler ausgelöst. Danach wird das Ergebnis des statischen Initialisierers zwischengespeichert ...
Michael Wiles
6

Ihnen fehlt die erforderliche Klassendefinition. Wird normalerweise dadurch verursacht, dass sich die erforderliche JAR nicht im Klassenpfad befindet.

Von der J2SE-API :

Die öffentliche Klasse NoClassDefFoundError erweitert LinkageError

Wird ausgelöst, wenn die Java Virtual Machine oder eine ClassLoader-Instanz versucht, die Definition einer Klasse zu laden (als Teil eines normalen Methodenaufrufs oder als Teil der Erstellung einer neuen Instanz mit dem neuen Ausdruck) und keine Definition der Klasse gefunden werden konnte.

Die gesuchte Klassendefinition war vorhanden, als die aktuell ausgeführte Klasse kompiliert wurde, aber die Definition kann nicht mehr gefunden werden.

ChssPly76
quelle
2
Der tatsächliche Name der fehlenden Klasse sollte sich irgendwo in einer verschachtelten Ausnahmemeldung befinden.
Stephen C
1

Ich hatte das gleiche Problem, weil die JAR-Bibliothek von einem anderen Linux-Benutzer (root) kopiert wurde und der angemeldete Benutzer (Prozess) nicht über ausreichende Berechtigungen zum Lesen des JAR-Dateiinhalts verfügte.

Kayvan Tehrani
quelle
0

Ich hatte das:

 class Util {
  static boolean isNeverAsync = System.getenv().get("asyncc_exclude_redundancy").equals("yes");
}

Sie können das Problem wahrscheinlich sehen, die env var gibt möglicherweise null anstelle von string zurück. Um meine Theorie zu testen, habe ich sie geändert in:

 class Util {
  static boolean isNeverAsync = false;
}

und das Problem ging weg. Schade, dass Java Ihnen nicht die genaue Stapelspur des Fehlers geben kann, irgendwie komisch.


quelle
0

Ich bin kürzlich unter Windows 10 auf diesen Fehler gestoßen. Es stellte sich heraus, dass Windows nach DLL-Dateien suchte, die für mein Projekt erforderlich waren, und sie nicht finden konnte, da sie im Systempfad PATH und nicht im CLASSPATH oder -Djava gesucht wurden .library.path

Jonathan Shaw
quelle
-2

Als ich diesen Fehler sah, wurde mir klar, dass ich OpenJDK verwendete. Es wurde behoben, nachdem ich stattdessen das Oracle JDK installiert hatte.

Allkenang
quelle