NoClassDefFoundError 발생원인 및 해결(ClassNotFoundException와 차이점)
일반적으로 NoClassDefFoundError 에러는 컴파일 시점에 존재했던 클래스가 런타임에 존재하지 않으면 발생하는 에러라고 알고 있다.
포스팅 최하단에 링크한 Stackoverflow의 질문 답변부분의 그림을 인용하면 Class A는 Class B, Class C에 의존성을 가지고 있다. 정상적으로 컴파일 후 런타임에서 Classpath에서 Class C가 없어진다면 JVM이 Class C를 로드할 수 없기 때문에 NoClassDefFoundError가 발생한다.
위 예제대로라면 단순히 NoClassDefFoundError가 발생하면 Classpath만의 문제라고 생각할 수 있겠지만 NoClassDefFoundError은 더 다양한 발생 이유가 존재한다. 이 차이를 알기 위해 java.lang.ClassNotFoundException과 java.lang.NoClassDefFoundError를 같이 살펴본다.
1. java.lang.ClassNotFoundException
이 익셉션은 Classpath에 로드하고자 하는 Class가 발견되지 않았을 때 발생한다. 보통은 빌드에 문제가 있는 경우로 clean이나 Class파일 삭제 후 재빌드를 수행하여 해결한다.
2. java.lang.NoClassDefFoundError
이 익셉션은 JVM이 내부의 클래스 정의 데이터 구조(class definition data structure)에서 Class를 찾지 못했다는 것을 나타낸다. 단순히 Classpath에서 Class를 로드하지 못했다는 것과 약간은 다르다.
일반적으로 과거에 Classpath에서 Class를 로드하려 시도했지만 실패하였고, 다시 해당 Class를 사용하려고 시도할 때 로드에 실패했던 전적이 있으니 로드를 시도하지도 않고 NoClassDefFoundError를 뱉는다. 과거의 로드실패는 ClassNotFoundException, ExceptionInInitializerError 또는 여러 다른 이유로부터 발생할 수 있다.
여기서 핵심은 NoClassDefFoundError의 발생은 단순히 Classpath의 문제는 아니라는 것이다.
아래 코드에서 SimpleCalculator의 static 초기화 구문은 에러를 발생시킨다. (static 초기화 구문에서 에러시 ExceptionInInitializerError가 발생한다.) 여기서 1차적으로 SimpleCalculator Class를 로드하려는데 실패하였고, 이후 다시 사용하려고 시도하면 이전의 실패를 기억하여 NoClassDefFoundError가 발생하게 된다.
public class NoClassDefFoundErrorDemo {
public static void main(String[] args) {
try {
// 아래에서 ExceptionInInitializerError 발생
SimpleCalculator calculator1 = new SimpleCalculator();
} catch (Throwable t) {
System.out.println(t);
}
// 아래에서 NoClassDefFoundError 발생
SimpleCalculator calculator2 = new SimpleCalculator();
}
}
public class SimpleCalculator {
static int undefined = 1 / 0; // 에러발생
}
정리해보면,
ClassNotFoundException과 NoClassDefFoundError 모두 비슷한 의미로 Class를 로드할 수 없음을 가리키나 해결을 위해 봐야 할 포인트는 조금 다르다는 것이다. NoClassDefFoundError의 경우 위 예제처럼 Classpath의 문제가 아닌 다른 내제적인 문제에서 발생할 수 있다.
개인적으로 Maven을 즐겨 쓰는데 NoClassDefFoundError가 발생하면 의존하는 라이브러리의 버전이 서로 맞지 않아 발생하는 경우가 대부분이었다.
더 많은 내용에 대해서는 아래 Stackoverflow의 링크를 남긴다.
stackoverflow.com/questions/34413/why-am-i-getting-a-noclassdeffounderror-in-java
'개발 > JAVA Trouble-Shooting' 카테고리의 다른 글
Cannot find symbol 원인 및 해결방법(Cannot resolve symbol, Symbol not found 등) (0) | 2020.12.13 |
---|---|
Scanner nextInt() 사용시 주의점 (nextLine() 스킵현상) (0) | 2020.12.11 |