개발/Trouble Shooting

클래스가 어디로 사라졌을까? ClassNotFoundException 완벽 가이드

ophelisis 2025. 12. 29. 10:12
반응형

1. ❓ ClassNotFoundException이란 무엇인가요?

ClassNotFoundException은 자바 가상 머신(JVM)이 **실행 시간(Runtime)**에 특정 클래스를 로드하려고 시도했지만, 클래스 패스(Classpath)에서 해당 클래스의 정의를 찾을 수 없을 때 발생하는 **체크드 예외(Checked Exception)**입니다.

주로 Class.forName(), ClassLoader.findSystemClass(), ClassLoader.loadClass() 등을 사용하여 문자열로 된 클래스 이름을 직접 넘겨줄 때 발생합니다.


2. 🔍 왜 발생하나요? (주요 원인)

  1. 클래스 패스 설정 누락: 필요한 .jar 파일이나 .class 파일이 프로젝트의 빌드 경로(Build Path)에 포함되지 않았을 때 발생합니다.
  2. 이름 오타: Class.forName("com.mysql.jdbc.Driver")와 같이 클래스 이름을 문자열로 입력할 때 패키지 명이나 클래스 명에 오타가 있는 경우입니다.
  3. 라이브러리 버전 불일치: 빌드 도구(Maven, Gradle) 설정 오류로 인해 컴파일 시점에는 있었던 클래스가 런타임 배포 환경에서는 빠져 있는 경우 발생합니다.
  4. 클래스 로더의 가시성: 상위 클래스 로더가 로드한 클래스를 하위 클래스 로더가 찾지 못하는 특수한 설정 문제일 수 있습니다.

3. ⚖️ NoClassDefFoundError와 무엇이 다른가요?

이 두 가지는 이름이 비슷해서 가장 많이 헷갈리는 부분입니다.

구분 ClassNotFoundException NoClassDefFoundError
종류 Exception (예외) Error (에러)
발생 시점 실행 중 동적으로 클래스 로드 시 컴파일 땐 있었으나 실행 시 사라졌을 때
원인 명시적으로 클래스를 찾으려다 실패 클래스 간 의존 관계에서 로드 실패

4. 🛠️ 해결 방법

✅ 1. 의존성 확인 (Maven/Gradle)

사용 중인 라이브러리가 pom.xml이나 build.gradle에 정확히 명시되어 있는지, 그리고 Refresh를 통해 라이브러리가 제대로 다운로드되었는지 확인하세요.

✅ 2. 클래스 이름 검증

패키지 경로를 포함한 전체 이름(Fully Qualified Name)이 정확한지 다시 한번 확인합니다.

  • 예: mysql-connector-j 8.0 이상에서는 com.mysql.cj.jdbc.Driver를 사용해야 합니다.

✅ 3. 빌드 결과물 확인

배포된 서버의 WEB-INF/lib 혹은 실행 중인 환경의 경로에 실제 .jar 파일이 들어있는지 확인해 보세요.


💡 시니어의 조언: '런타임 동적 로딩'의 대가입니다

ClassNotFoundException은 주로 설정 파일(XML, Property)을 기반으로 객체를 생성하는 프레임워크 내부DB 드라이버 로딩 시점에 자주 발생합니다.

현대적인 개발 환경에서는 IDE가 컴파일 시점에 웬만한 누락을 다 잡아주지만, 리플렉션(Reflection)을 사용하는 고급 기술을 다룰 때는 이 예외를 처리하는 능력이 필수적입니다. 예외가 발생하면 가장 먼저 로그를 보고 **"어떤 클래스 이름"**을 못 찾고 있는지 확인하는 습관을 들이세요!

반응형