NoClassDefFoundError (NCDFE) происходит, когда ваш код выполняет «new Y ()» и не может найти класс Y.
Может просто случиться так, что Y отсутствует в загрузчике классов, как предлагают другие комментарии, но возможно, что класс Y не подписан или имеет недопустимую подпись, или что Y загружен другим загрузчиком классов, невидимым для вашего кода или даже то, что Y зависит от Z, который не может быть загружен по любой из вышеуказанных причин.
Если это произойдет, JVM запомнит результат загрузки X (NCDFE) и будет просто выдавать новый NCDFE каждый раз, когда вы запрашиваете Y, не сообщая вам, почему:
класс {
статический класс b {}
public static void main (String args []) {
System.out.println («Первая попытка нового b ():»);
try {new b (); } catch (Throwable t) {t.printStackTrace ();}
System.out.println ("\ nВторичная попытка нового b ():");
try {new b (); } catch (Throwable t) {t.printStackTrace ();}
}
}
сохраните это как a.java где-нибудь
Код просто пытается дважды создать новый класс «b», кроме этого, в нем нет ошибок и он ничего не делает.
Скомпилируйте код с помощью javac a.java
, затем запустите, вызвав java -cp . a
- он должен просто распечатать две строки текста, и он должен работать без ошибок.
Затем удалите файл «$ b.class» (или заполните его мусором, или скопируйте поверх него a.class), чтобы имитировать отсутствующий или поврежденный класс. Вот что происходит:
Первая попытка нового b ():
java.lang.NoClassDefFoundError: a $ b
в a.main (a.java:5)
Вызывается: java.lang.ClassNotFoundException: a $ b
на java.net.URLClassLoader $ 1.run (URLClassLoader.java:200)
at java.security.AccessController.doPrivileged (собственный метод)
на java.net.URLClassLoader.findClass (URLClassLoader.java:188)
в java.lang.ClassLoader.loadClass (ClassLoader.java:307)
at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:301)
в java.lang.ClassLoader.loadClass (ClassLoader.java:252)
в java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)
... 1 более
Вторая попытка нового b ():
java.lang.NoClassDefFoundError: a $ b
в домене (a.java:7)
Первый вызов приводит к исключению ClassNotFoundException (генерируемому загрузчиком классов, когда он не может найти класс), которое должно быть заключено в непроверенную NoClassDefFoundError, так как код в вопросе ( new b()
) должен просто работать.
Вторая попытка, конечно, тоже потерпит неудачу, но, как вы можете видеть, исключенное завершение больше не существует, потому что ClassLoader, похоже, запоминает неудачные загрузчики классов. Вы видите только NCDFE без какой-либо подсказки о том, что на самом деле произошло.
Поэтому, если вы когда-нибудь увидите NCDFE без основной причины, вам нужно посмотреть, сможете ли вы отследить, когда класс был загружен в первый раз, чтобы найти причину ошибки.
-verbose
(например-verbose:class -verbose:jni
) справок - но ниже в своем ответе моги сообщают, что это не дает никакой дополнительной полезной информации :(