1. ❓ ClassNotFoundException이란 무엇인가요?
ClassNotFoundException은 자바 가상 머신(JVM)이 **실행 시간(Runtime)**에 특정 클래스를 로드하려고 시도했지만, 클래스 패스(Classpath)에서 해당 클래스의 정의를 찾을 수 없을 때 발생하는 **체크드 예외(Checked Exception)**입니다.
주로 Class.forName(), ClassLoader.findSystemClass(), ClassLoader.loadClass() 등을 사용하여 문자열로 된 클래스 이름을 직접 넘겨줄 때 발생합니다.
2. 🔍 왜 발생하나요? (주요 원인)
- 클래스 패스 설정 누락: 필요한 .jar 파일이나 .class 파일이 프로젝트의 빌드 경로(Build Path)에 포함되지 않았을 때 발생합니다.
- 이름 오타: Class.forName("com.mysql.jdbc.Driver")와 같이 클래스 이름을 문자열로 입력할 때 패키지 명이나 클래스 명에 오타가 있는 경우입니다.
- 라이브러리 버전 불일치: 빌드 도구(Maven, Gradle) 설정 오류로 인해 컴파일 시점에는 있었던 클래스가 런타임 배포 환경에서는 빠져 있는 경우 발생합니다.
- 클래스 로더의 가시성: 상위 클래스 로더가 로드한 클래스를 하위 클래스 로더가 찾지 못하는 특수한 설정 문제일 수 있습니다.
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)을 사용하는 고급 기술을 다룰 때는 이 예외를 처리하는 능력이 필수적입니다. 예외가 발생하면 가장 먼저 로그를 보고 **"어떤 클래스 이름"**을 못 찾고 있는지 확인하는 습관을 들이세요!
'개발 > Trouble Shooting' 카테고리의 다른 글
| 정해진 선을 넘지 마세요: ArrayIndexOutOfBoundsException 완벽 가이드 (0) | 2025.12.29 |
|---|---|
| 자바의 영원한 숙제: NullPointerException (NPE) 완벽 가이드 (0) | 2025.12.29 |
| 데이터베이스와의 소통 불능: SQLException 완벽 가이드 (0) | 2025.12.29 |
| 데이터 통신의 첫 번째 관문: IOException 완벽 이해하기 (0) | 2025.12.29 |
| 재귀의 늪에 빠지다: StackOverflowError 원인과 해결 방법 (0) | 2025.12.29 |