NoClassDefFoundError (NCDFE) происходит, когда ваш код выполняет "new Y ()" и не может найти класс Y.
Это может быть просто то, что Y отсутствует в загрузчике классов, как предлагают другие комментарии, но возможно, что класс Y не подписан или имеет недопустимую сигнатуру, или что Y загружен другим загрузчиком классов, который не виден к вашему коду, или даже то, что Y зависит от Z, который не может быть загружен по любой из вышеперечисленных причин.
Если это произойдет, то JVM запомнит результат загрузки X (NCDFE) и будет просто выдавать новый NCDFE каждый раз, когда вы запрашиваете Y, не сообщая, почему:
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();}
}
}
сохранить это как a.java где-нибудь
Код просто пытается дважды создать новый класс "b", кроме этого, в нем нет ошибок и он ничего не делает.
Скомпилируйте код с помощью javac a.java
, затем запустите, вызвав java -cp . a
- он должен просто напечатать две строки текста, и он должен работать без ошибок.
Затем удалите файл «a $ b.class» (или заполните его мусором, или скопируйте поверх него a.class), чтобы имитировать отсутствующий или поврежденный класс. Вот что происходит:
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)
Первый вызов приводит к исключению ClassNotFoundException (генерируемому загрузчиком классов, когда он не может найти класс), которое должно быть заключено в непроверенную NoClassDefFoundError, поскольку рассматриваемый код (new b()
) должен просто работать.
Вторая попытка, конечно, тоже потерпит неудачу, но, как вы можете видеть, исключенное завернутое исключение больше не существует, потому что ClassLoader, похоже, запоминает сбой загрузчиков классов. Вы видите только NCDFE, абсолютно не имея ни малейшего понятия о том, что на самом деле произошло.
Так что, если вы когда-нибудь увидите NCDFE без первопричины, вам нужно посмотреть, сможете ли вы отследить, когда класс был загружен в первый раз, чтобы найти причину ошибки.