Java에서 클래스를 로드하려고 할 때, 클래스 로더(ClassLoader)가 지정된 경로에서 해당 클래스를 찾지 못하면 ClassNotFoundException이 발생합니다.
이 예외는 Java 프로그램을 실행하는 도중이나, Class 클래스의 forName() 메서드 또는 ClassLoader 클래스의 loadClass() 메서드를 사용해 클래스를 명시적으로 로드할 때 발생할 수 있습니다. 이 두 메서드는 클래스 이름을 나타내는 문자열을 인자로 받아 지정된 클래스를 로드합니다.
따라서 이러한 메서드에 클래스 이름을 전달할 때는 반드시 다음 두 가지를 확인해야 합니다.
메서드에 전달하는 클래스 이름이 정확해야 합니다. 패키지 이름까지 포함한 완전한 클래스 이름(FQCN)의 오타가 없어야 합니다.
지정된 클래스(패키지 구조 포함)가 현재 작업 디렉터리에 존재하거나, 해당 경로가 환경 변수 classpath에 등록되어 있어야 합니다.
예제 코드
D:// 디렉터리에 Sample이라는 클래스를 생성하고 아래와 같이 컴파일했다고 가정해 보겠습니다.
package myPackage.example;
public class Sample {
static {
System.out.println("The class named Sample loaded successfully.........");
}
}
컴파일
D:\>javac -d . Sample.java
위 명령을 실행하면 현재 디렉터리에 myPackage.example 패키지가 생성되고, 그 안에 Sample 클래스의 .class 파일이 만들어집니다. 따라서 이 클래스를 로드하려면 해당 파일이 동일한 디렉터리 구조 안에 있어야 하며, Class.forName() 또는 loadClass()에는 패키지 이름을 포함한 완전한 클래스 이름을 전달해야 합니다.
예제 코드
public class ClassNotFoundExample {
public static void main(String args[]) {
try {
Class.forName("myPackage.exampl.Sample");
}catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
발생하는 예외
위 프로그램을 실행하면 패키지 이름의 철자(example이 아니라 exampl)가 잘못 입력되었기 때문에 다음과 같은 예외가 발생합니다.
D:\>java ClassNotFoundExample
java.lang.ClassNotFoundException: myPackage.exampl.Sample
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
at ClassNotFoundExample.main(ClassNotFoundExample.java:4)
다른 디렉터리에서 특정 클래스에 접근하려면 다음 중 하나를 대상으로 클래스패스(classpath)를 설정해야 합니다.
.class 파일이 포함된 폴더(최상위 패키지의 상위 디렉터리)
또는 해당 클래스가 포함된 jar 파일
이번에는 철자 오류를 수정하고, E:// 디렉터리에 있는 Java 파일에서 해당 클래스를 로드하려고 한다고 가정해 보겠습니다.
예제 코드
public class ClassNotFoundExample {
public static void main(String args[]) {
try {
Class.forName("myPackage.example.Sample");
}catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
여전히 발생하는 예외
그러나 지정된 클래스의 .class 파일이 담긴 패키지(또는 이를 포함하는 jar 파일)가 현재 디렉터리에도 없고, 환경 변수 classpath의 경로 목록에도 등록되어 있지 않기 때문에 동일한 예외가 계속 발생합니다.
E:\>java ClassNotFoundExample
java.lang.ClassNotFoundException: myPackage.example.Sample
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
at ClassNotFoundExample.main(ClassNotFoundExample.java:4)
이 문제를 해결하려면 필요한 클래스가 들어 있는 패키지가 위치한 디렉터리, 즉 "D://"를 클래스패스로 설정한 뒤 프로그램을 다시 실행하면 됩니다. 그러면 클래스가 정상적으로 로드됩니다.
E:\>javac ClassNotFoundExample.java E:\>java ClassNotFoundExample The class named Sample loaded successfully.........