Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바 ClassNotFoundException과 NoClassDefFoundError의 차이점 완벽 정리

자바 개발을 하다 보면 런타임에 클래스를 찾지 못해 발생하는 두 가지 대표적인 오류, ClassNotFoundExceptionNoClassDefFoundError를 마주하게 됩니다. 두 오류 모두 JVM이나 클래스로더(ClassLoader)가 실행 시점에 필요한 클래스를 로딩하지 못할 때 발생하지만, 성격과 발생 원인은 분명히 다릅니다.

ClassNotFoundException은 컴파일러가 반드시 처리하도록 요구하는 체크 예외(checked exception)이며, NoClassDefFoundError는 처리 여부가 선택적인 언체크(unchecked) 범주에 속하는 Error입니다.

클래스로더는 서로 다른 소스에서 클래스를 불러오는데, 이 과정에서 필요한 JAR 파일이 누락되었거나 클래스패스(classpath) 설정이 잘못되면 런타임에 클래스를 로드하지 못해 문제가 발생할 수 있습니다.

ClassNotFoundException란?

ClassNotFoundException은 리플렉션(Reflection)을 사용해 런타임에 동적으로 클래스를 로드하려 할 때, 해당 클래스 파일이 존재하지 않으면 발생합니다. 클래스를 런타임에 로드하기 때문에 컴파일 시점에는 어떠한 검사도 이루어지지 않습니다.

ClassNotFoundException 예제

public class ClassNotFoundExceptionTest {
    public static void main(String[] args) {
        try {
            Class.forName("Test");
        } catch (ClassNotFoundException cnfe) {
            System.err.println("존재하지 않는 클래스를 검색하려고 합니다. " + cnfe);
        }
    }
}

실행 결과

존재하지 않는 클래스를 검색하려고 합니다. java.lang.ClassNotFoundException: Test

NoClassDefFoundError란?

NoClassDefFoundError는 특정 클래스가 클래스패스에 있는 상태로 컴파일되었지만, 실행 시점에는 같은 클래스를 더 이상 찾을 수 없을 때 발생합니다. 가장 흔한 원인은 JAR 파일의 누락입니다. 자바 API 문서에 따르면 "현재 실행 중인 클래스가 컴파일될 당시에는 검색 대상 클래스의 정의가 존재했지만, 더 이상 그 정의를 찾을 수 없다"는 의미입니다.

NoClassDefFoundError 예제

class Test1 {
    public void show() {
        System.out.println("show() 메서드 호출");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Test1 t = new Test1();
        t.show();
    }
}

위 코드를 컴파일하면 Test1.classTest2.class 두 개의 클래스 파일이 생성됩니다. 이후 Test2를 실행하기 전에 Test1.class 파일을 삭제하면 아래와 같이 NoClassDefFoundError가 발생합니다.

실행 결과

Exception in thread "main" java.lang.NoClassDefFoundError: Test1
        at Test2.main(Test2.java:9)

핵심 차이점 비교

구분ClassNotFoundExceptionNoClassDefFoundError
유형체크 예외(checked exception)Error (언체크)
발생 시점리플렉션 등으로 런타임에 클래스를 명시적으로 로드할 때컴파일 시점에는 존재했으나 런타임에 클래스가 없을 때
대표 원인Class.forName(), loadClass() 등으로 존재하지 않는 클래스 로드 시도JAR 파일 누락, 클래스패스 변경 또는 오류
처리 방법try-catch로 반드시 처리해야 함처리는 선택 사항

정리하면, ClassNotFoundException은 런타임에 동적으로 클래스를 로드하려다 실패한 경우의 예외이고, NoClassDefFoundError는 컴파일 당시에는 있었던 클래스가 실행 환경에서 사라졌을 때 발생하는 에러입니다. 두 오류의 발생 조건을 정확히 이해하면 클래스패스 관련 문제를 훨씬 빠르게 진단하고 해결할 수 있습니다.