Помилка "NoClassDefFoundError: Не вдалося ініціалізувати клас"


77

Коли я запускаю свій проект, я отримую численні результати цієї помилки:

9 вересня 2009 р. 8:22:23 org.apache.catalina.core.StandardWrapperValve invoke
ТЕЖЕ: Servlet.service () для сервлета Джерсі викинуло виняток
java.lang.NoClassDefFoundError: Не вдалося ініціалізувати клас SpringFactory
        у com.point2.prospect.persistence.hibernate.HibernateTransactionInterceptor.doFilter (HibernateTrans
actionInterceptor.java:17)
        на org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:235)
        на org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206)
        на com.point2.prospect.restapi.ServerErrorInterceptor.doFilter (ServerErrorInterceptor.java:27)
        на org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:235)
        на org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206)
        на org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:233)
        на org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:191)
        на org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:128)
        на org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:102)
        на org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:109)
        на org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:286)
        на org.apache.coyote.http11.Http11Processor.process (Http11Processor.java:845)
        на org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process (Http11Protocol.java:583)
        на org.apache.tomcat.util.net.JIoEndpoint $ Worker.run (JIoEndpoint.java:447)
        на java.lang.Thread.run (Thread.java:619)

Я помічаю, що ця проблема має характер запитувань по всьому Інтернету, але без реальних відповідей. Що є загальною причиною такого роду помилок?

Відповіді:


204

Помилка NoClassDefFound - це туманна помилка, яка часто приховує більш серйозну проблему. Це не те саме, що ClassNotFoundException (який викидається, коли класу просто немає).

NoClassDefFound може вказувати, що класу немає, як вказують javadocs, але він зазвичай викидається, коли завантажувач класів завантажує байти для класу і викликає на них "defineClass". Також уважно перевірте повну трасу стека на наявність інших підказок чи можливих винятків "причини" (хоча у вашій конкретній зворотній трасі не показано жодного).

Перше місце, яке потрібно шукати, коли ви отримуєте NoClassDefFoundError, - це статичні біти вашого класу, тобто будь-яка ініціалізація, яка відбувається під час визначення класу. Якщо це не вдається, буде викинуто NoClassDefFoundError - передбачається викинути ExceptionInInitializerError і вказати деталі проблеми, але, на мій досвід, це рідко. Він зробить ExceptionInInitializerError лише при першій спробі визначити клас, після чого просто викине NoClassDefFound. Тож подивіться на попередні журнали.

Таким чином, я б запропонував переглянути код у цьому рядку HibernateTransactionInterceptor і побачити, що він вимагає. Здається, він не може визначити клас SpringFactory. Тож, можливо, перевірте код ініціалізації в цьому класі, що може допомогти. Якщо ви можете його налагодити, зупиніть його в останньому рядку вище (17) та налагодьте, щоб ви могли спробувати знайти точний рядок, що викликає виняток. Також перевірте вище в журналі, якщо вам дуже пощастить, може статися ExceptionInInitializerError.


22
Дякую. Звернувши свою увагу на статичні блоки ініціалізатора, ми заощадили години загострення.
Борис Брудного

1
"тобто будь-яка ініціалізація, яка відбувається під час визначення класу" - Дякую!
Matt MacLean

2
Ще одна хороша ідея - це перенести журнал у файл і шукати java.lang.ClassNotFoundException. Там може бути хтось бездомний, який повідомить вам, який клас він намагався завантажити, що спричинило всі винятки NoClassDefFoundError. Працював у мене.
Райан Шилінгтон,

І щось додати ... Я також виявив, що ви отримуєте NoClassDefFoundError, якщо клас не знаходить потрібного йому класу. Отже, ви отримаєте виняток для класу, який не знайдено, для класу, який він не може знайти, та NoClassDefFoundError для класу, який визначається.
Michael Wiles

1
Причиною цього є те, що статичний ініціалізатор запускається лише один раз ... це правило зберігається послідовно. Отже, якщо він запускається один раз, і він не вдається, він видає помилку ExceptionInInitializer. Після цього він кешує результат статичного ініціалізатора ...
Майкл

6

Вам не вистачає необхідного визначення класу; як правило, спричинене тим, що необхідний JAR відсутній у шляху до класу.

З API J2SE :

відкритий клас NoClassDefFoundError розширює LinkageError

Викидається, якщо віртуальна машина Java або екземпляр ClassLoader намагається завантажити у визначенні класу (як частина звичайного виклику методу або як частина створення нового екземпляра за допомогою нового виразу), і жодного визначення класу не вдається знайти.

Визначення класу, який шукали, існувало, коли виконувався в даний час клас, але визначення більше неможливо знайти.


2
Фактичне ім'я класу, якого немає, повинно бути десь у вкладеному повідомленні про виняток.
Stephen C

1

Я зіткнувся з тією ж проблемою, оскільки бібліотека jar була скопійована іншим користувачем Linux (root), а зареєстрований користувач (процес) не мав достатніх привілеїв для читання вмісту файлу jar.


0

У мене було таке:

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

можливо, ви бачите проблему, env var може повернути null замість рядка. Тож, щоб перевірити свою теорію, я змінив її на:

 class Util {
  static boolean isNeverAsync = false;
}

і проблема пішла. Шкода, що Java не може дати вам точний стек помилки, хоч і дивно.


0

Нещодавно я зіткнувся з цією помилкою в Windows 10. Виявилося, що Windows шукав файли .dll, необхідні для мого проекту, і не міг їх знайти, оскільки він шукає їх у системному шляху, PATH, а не в CLASSPATH або -Djava .library.path


-2

Зрозумів, що я використовую OpenJDK, коли побачив цю помилку. Виправлено, як тільки я встановив Oracle JDK.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.