Java

[Java] ClassNotFoundException VS NoClassDefFoundError

SeungbeomKim 2024. 2. 6. 01:09

Java 예외 중에서, 런타임 시 클래스 파일을 사용할 수 없기 때문에 발생하는 에러인 ClassNotFoundException, NoClassDefFoundError에 대해 알아보도록 하겠습니다. 

 

이 둘의 공통점은 모두 JVM이 클래스 경로에서 요청된 클래스를 찾을 수 없을 때 발생하는 에러인데요. 이 둘의 특징과 차이점에 대해서도 대해서도 설명드리겠습니다. 

 

1. ClassNotFoundException

ClassNotFoundException

 

  • 클래스 로더가 애플리케이션의 클래스 경로에 정의되어 있는 클래스를 찾지 못할 때 발생합니다.
  • Class.forName(), ClassLoader.loadClass(), ClassLoaderFindSystemClass()를 사용하여 클래스를 로드하려고 할 때 주로 발생합니다.
  • 리플렉션을 사용하는 동안 java.lang.ClassNotFoundException에 주의해야 합니다.

ex) JDBC Dependency를 추가하지 않고 JDBC 드라이버 클래스를 로드

@Test(expected = ClassNotFoundException.class)
public void givenNoDrivers_whenLoadDriverClass_thenClassNotFoundException() 
  throws ClassNotFoundException {
      Class.forName("oracle.jdbc.driver.OracleDriver");
}

 

JDBC 의존성을 추가하지 않고 JDBC Driver를 호출하였기에 기대 결과에 맞게(ClassNotFoundException 발생) 테스트는 통과할 것입니다.

 

2. NoClassDefFoundError

NoClassDefFoundError

  • NoClassDefFoundError는 치명적인 오류인데, JVM이 new 키워드를 사용하여 인스턴스를 생성하거나, 메서드 호출로 클래스를 로드하려고 할 때, 클래스 정의를 찾을 수 없을 경우에 발생하는 에러입니다.
  • 컴파일러가 클래스를 성공적으로 컴파일할 수 있지만, Java 런타임이 클래스 파일을 찾을 수 없는 경우 오류가 발생합니다.
  • 일반적으로 정적 블록을 실행하거나 클래스의 정적 필드를 초기화하는 동안 예외가 발생하여 클래스 초기화가 실패할 때 발생합니다.

ex) 필드 초기화시 예외를 터지는 임의 클래스와 이를 호출하는 클래스의 경우 

public class ClassWithInitErrors {
    static int data = 1 / 0;
}

public class NoClassDefFoundErrorExample {
    public ClassWithInitErrors getClassWithInitErrors() {
        ClassWithInitErrors test;
        try {
            test = new ClassWithInitErrors();
        } catch (Throwable t) {
            System.out.println(t);
        }
        test = new ClassWithInitErrors();
        return test;
    }
}

 

@Test(expected = NoClassDefFoundError.class)
public void givenInitErrorInClass_whenloadClass_thenNoClassDefFoundError() {
 
    NoClassDefFoundErrorExample sample = new NoClassDefFoundErrorExample();
    sample.getClassWithInitErrors();
}

 

ClassWithInitErrors 초기화에서 예외가 터지기에, ClassWithInitErrors 객체를 생성하려고 하면 ExceptionInitializerError가 발생하게 됩니다.

 

<차이점>

ClassNotFoundException

  • 런타임에만 클래스를 로드하려고 시도하는 동안 Java 런타임에서 ClassNotFoundException 에러가 발생합니다. (클래스를 찾을 수 없습니다)

NoClassDefFoundError

  • 클래스가 컴파일 타임에 존재했지만, Java 런타임이 런타임 중에 Java 클래스 경로에서 해당 클래스를 찾을 수 없을 때 발생합니다.

 

'Java' 카테고리의 다른 글

[Java] Garbage Collection  (1) 2024.12.05
[Java] Exception  (0) 2023.08.21