NCDFE (NoClassDefFoundError)는 코드에서 "new Y ()"를 실행하고 Y 클래스를 찾을 수 없을 때 발생합니다.
다른 의견에서 알 수 있듯이 Y가 클래스 로더에서 누락되었을 수 있지만 Y 클래스가 서명되지 않았거나 서명이 잘못되었거나 코드에 표시되지 않는 다른 클래스 로더에 의해 Y가로드되었을 수 있습니다. 또는 Y가 Z에 의존하여 위의 이유로로드 할 수 없습니다.
이 경우 JVM은 X (NCDFE)로드 결과를 기억하며 Y를 요청할 때마다 이유를 알리지 않고 새 NCDFE를 던집니다.
클래스 {
정적 클래스 b {}
공개 정적 무효 메인 (문자열 인수 []) {
System.out.println ( "첫 번째 시도 새 b () :");
{new b ();를 시도하십시오 } catch (Throwable t) {t.printStackTrace ();}
System.out.println ( "\ n 둘째 새 b () :") 시도;
{new b ();를 시도하십시오 } catch (Throwable t) {t.printStackTrace ();}
}
}
이것을 어딘가에 a.java로 저장하십시오.
이 코드는 단순히 새로운 "b"클래스를 두 번 인스턴스화하려고 시도합니다. 그 외에는 버그가 없으며 아무 것도하지 않습니다.
로 코드를 컴파일 한 javac a.java
다음 호출하여 a를 실행하십시오. java -cp . a
두 줄의 텍스트를 인쇄하면 오류없이 정상적으로 실행됩니다.
그런 다음 "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)
java.security.AccessController.doPrivileged (네이티브 메소드)
java.net.URLClassLoader.findClass (URLClassLoader.java:188)에서
java.lang.ClassLoader.loadClass (ClassLoader.java:307)에서
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.main (a.java:7)에서
첫 번째 호출은 ClassNotFoundException (클래스를 찾을 수 없을 때 클래스 로더에 의해 발생)을 초래하며, 문제의 코드 ( new b()
)가 작동 하기 때문에 검사되지 않은 NoClassDefFoundError로 랩핑 되어야합니다.
두 번째 시도는 물론 실패하지만, 클래스 로더가 실패한 클래스 로더를 기억하는 것처럼 보이기 때문에 랩 된 예외는 더 이상 볼 수 없습니다. 당신은 실제로 일어난 일에 대한 단서가없는 NCDFE 만 봅니다.
따라서 근본 원인이없는 NCDFE가 표시되는 경우 오류가 발생한 원인을 찾기 위해 클래스가 처음로드 된 시점까지 추적 할 수 있는지 확인해야합니다.
-verbose
(예를 들어-verbose:class -verbose:jni
) 도움으로 JVM을 실행하는 것을 발견 하지만 유용한 정보를 제공하지 않는다는 mogsie의 답변 아래 :(