웹사이트 검색

java.lang.NoClassDefFoundError


java.lang.NoClassDefFoundError는 필수 클래스가 클래스 경로에서 발견되지 않아 JVM이 이를 메모리에 로드할 수 없을 때 발생하는 런타임 오류입니다.

java.lang.NoClassDefFoundError

  • NoClassDefFoundError는 런타임 오류이므로 이를 예상하고 복구하는 것은 애플리케이션 범위를 벗어납니다.
  • java.lang.NoClassDefFoundError는 런타임 오류이며 컴파일 시간에 발생하지 않습니다.
  • NoClassDefFoundError는 JVM이 필요한 클래스를 찾을 수 없다고 명시되어 있으므로 디버그하기가 매우 쉽습니다. 따라서 클래스 경로 구성을 확인하여 필수 클래스가 누락되지 않았는지 확인하십시오.

NoClassDefFoundError 클래스 다이어그램

java.lang.NoClassDefFoundError 이유

먼저 런타임에 NoClassDefFoundError가 발생하는 시나리오를 복제해 보겠습니다. 아래와 같은 자바 클래스가 있다고 합시다.

public class Data {

	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
}

위의 클래스는 다른 사용자 정의 Java 클래스에 의존하지 않고 Java 내장 클래스만 사용합니다. 같은 디렉토리에서 Data 클래스를 사용할 또 다른 클래스를 만들어 봅시다.

public class DataTest {

	public static void main(String[] args) {
		Data data = new Data();
		data.setId(10);
		System.out.println("Data Id = "+data.getId());
	}

}

이제 DataTest 클래스를 컴파일하고 아래와 같이 실행해 봅시다.

pankaj:temp pankaj$ ls
Data.java	DataTest.java
pankaj:temp pankaj$ javac DataTest.java 
pankaj:temp pankaj$ ls 
Data.class	Data.java	DataTest.class	DataTest.java
pankaj:temp pankaj$ java DataTest
Data Id = 10
pankaj:temp pankaj$

지금까지 모든 것이 괜찮습니다. 이제 Data 클래스 파일을 다른 곳으로 옮긴 다음 DataTest 클래스를 실행해 보겠습니다. 컴파일 오류가 발생하므로 다시 컴파일하지 않습니다.

pankaj:temp pankaj$ mv Data.java Data.class ../
pankaj:temp pankaj$ ls
DataTest.class	DataTest.java
pankaj:temp pankaj$ java DataTest
Exception in thread "main" java.lang.NoClassDefFoundError: Data
	at DataTest.main(DataTest.java:5)
Caused by: java.lang.ClassNotFoundException: Data
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 1 more
pankaj:temp pankaj$ 

java.lang.NoClassDefFoundError를 해결하는 방법은 무엇입니까?

위의 예에서 이 오류의 유일한 이유는 필요한 클래스가 컴파일 타임에는 사용 가능했지만 런타임에는 사용할 수 없었기 때문임을 명확하게 확인할 수 있습니다. 다음을 확인하여 NoClassDefFoundError 오류를 수정할 수 있습니다.

  • Check the exception stack trace to know exactly which class throw the error and which is the class not found by java.

  • Next step is to look for classpath configuration, sometimes we compile our classes in Eclipse or some other environment and run in some other environment and we can miss classpath configurations. For example, I can fix above issue easily by adding the directory which contains Data class to the classpath like below.

    pankaj:temp pankaj$ java -classpath .:.. DataTest
    Data Id = 10
    pankaj:temp
    

    Remember that earlier I had moved Data class to previous directory.

  • Most of the times, NoClassDefFoundError comes with applications running on some server as web application or web services, in that case check if the required jars are part of the WAR file or not. For example, below maven configuration will not package jar file when generating WAR file.

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    

    But we need it for creating a servlet based web application, usually this jar is always part of Tomcat or any other application server.

여기까지가 java.lang.NoClassDefFoundError를 빠르게 살펴보기 위한 것입니다. 이 오류가 언제 발생하고 어떻게 쉽게 해결할 수 있는지에 대한 충분한 아이디어를 찾으시기 바랍니다. 참조: Java의 예외 처리