1. 문제 정의
검증 환경
본 절은 원문 사례·문서에 등장한 버전/도구를 정리한 것이다. 별도 실험실 재현이 명시되지 않은 항목은 일반화하지 않는다.
| 항목 | 본문·원문에서 확인된 범위 |
|---|---|
| 런타임/도구 | JDK 11 |
| 런타임/도구 | JDK 8 |
| 런타임/도구 | JDK 1 |
| 런타임/도구 | JDK 9 |
| 런타임/도구 | JDK 17 |
| 런타임/도구 | Java 8 |
| 런타임/도구 | Java 7 |
| 런타임/도구 | Windows |
| 문서 정리일 | 2026-09-02 |
- OS/CI 세부 값은 프로젝트마다 다르므로, 적용 전 로컬에서 동일 오류 메시지를 재확인한다.
Java 애플리케이션을 실행하는 순간 아래와 같은 예외를 만났다면, 그 원인은 시작부터 버전 문제입니다. 대표적인 에러 문구는 다음과 같습니다.
| |
더 최신 JRE에서는 메시지가 더 자세해져 어떤 버전이 문제인지 그대로 알려줍니다.
| |
한 줄 요약: 컴파일된 .class 파일의 major 버전이 실행 중인 JRE가 지원하는 버전보다 높아서 클래스 로더가 변환할 수 없는 상황입니다.
증상 fingerprint
| 항목 | 값 |
|---|---|
| 예외 타입 | java.lang.UnsupportedClassVersionError |
| 발생 단계 | 클래스 로딩 시점 (런타임, ClassLoader.defineClass1) |
| 바로 단서가 되는 숫자 | major.minor version 51.0 처럼 major 숫자 |
| 흔한 오해 | “패키지가 빠졌다 / JAR이 없다"로 착각하기 쉬움 — 실제로는 버전 불일치 |
| 빠른 판단 기준 | 에러의 major 숫자를 아래 버전표와 비교해 실행 JRE가 그 이하인지 확인 |
2. 원인 탐구 — 왜 발생하는가
Java의 javac는 -target(이후 권장되는 -release) 옵션을 바꾸지 않으면 컴파일러 자신의 버전으로 클래스 파일을 생성합니다. 즉 JDK 11로 컴파일하면 클래스 파일 major 버전이 55가 되고, 이 클래스를 JDK 8(JRE 52까지 인식)에서 실행하면 UnsupportedClassVersionError가 발생합니다.
값의 방향만 기억하면 됩니다.
| |
영향을 받는 버전: Java 클래스 파일 major 버전 매핑
에러 메시지에 나오는 major 숫자가 어떤 Java SE 버전의 클래스 파일인지 확인합니다. (출처: Wikipedia — Java class file)
| Java SE 버전 | major 버전 | minor |
|---|---|---|
| Java SE 24 | 68 | 0 |
| Java SE 23 | 67 | 0 |
| Java SE 22 | 66 | 0 |
| Java SE 21 | 65 | 0 |
| Java SE 20 | 64 | 0 |
| Java SE 19 | 63 | 0 |
| Java SE 18 | 62 | 0 |
| Java SE 17 | 61 | 0 |
| Java SE 16 | 60 | 0 |
| Java SE 15 | 59 | 0 |
| Java SE 14 | 58 | 0 |
| Java SE 13 | 57 | 0 |
| Java SE 12 | 56 | 0 |
| Java SE 11 | 55 | 0 |
| Java SE 10 | 54 | 0 |
| Java SE 9 | 53 | 0 |
| Java SE 8 | 52 | 0 |
| Java SE 7 (J2SE 7) | 51 | 0 |
| Java SE 6.0 | 50 | 0 |
| Java SE 5.0 | 49 | 0 |
| JDK 1.4 | 48 | 0 |
| JDK 1.3 | 47 | 0 |
| JDK 1.2 | 46 | 0 |
| JDK 1.1 | 45 | 0 |
위 예제의 major.minor version 51.0은 **Java SE 7(J2SE 7)**로 컴파일된 클래스라는 뜻이므로, 실행 중인 JRE가 Java 7 미만이라면 에러가 나는 것입니다.
3. 근본 원인 분석
표면 증상은 “클래스가 로드되지 않는다"지만, 근본 원인은 컴파일 환경과 실행 환경의 JVM(JDK/JRE) 버전이 서로 다르기 때문입니다. 실제 현장에서는 아래 중 하나가 원인입니다.
| 원인 후보 | 확인 명령 | 맞는 경우의 증상 | 해결 방향 |
|---|---|---|---|
| 실행 JRE가 낮음 | java -version 가 에러 major 숫자의 버전보다 낮음 | 어떤 클래스를 띄워도 같은 에러 | JRE를 클래스 버전 이상으로 업그레이드 |
| 컴파일 JDK가 높음 | javac -version 이 실행 JRE보다 높음 | 방금 컴파일한 클래스에서 발생 | -target/-release로 하위 버전 호환 컴파일 |
JAVA_HOME/PATH 불일치 | 위 두 명령의 버전이 서로 다름 | Maven/Gradle/build 도구가 낡은 JRE를 잡음 | JAVA_HOME/PATH를 동일 버전으로 통일 |
| 라이브러리(JAR)의 버전이 높음 | 특정 JAR 로드 시에만 발생 | 외부 라이브러리가 높은 자바로 컴파일됨 | 해당 라이브러리 버전 낮추거나 JRE 업그레이드 |
| IDE 빌드 컴파일러 설정 | Eclipse 등 프로젝트 컴파일러 compliance 기준 | IDE에서 재컴파일 후에만 에러 | IDE 컴파일러 compliance/target 컴파일러 버전 일치 |
위 표의 마지막 두 후보는 원글 답변과 일반적인 점검 기준에서 추가한 내용으로, 환경에 따라 다를 수 있습니다.
핵심: PATH를 문제로 오인하는 경우가 많지만, 근본은 PATH의 java(JRE)가 javac(JDK)가 만든 클래스 버전을 따라가지 못하는 것입니다. JDK는 JRE를 포함하지만, IDE나 빌드 도구(yum/apt로 설치한 openjdk 등)에 여러 버전이 깔려 있고 JAVA_HOME이 옛 버전을 가리키면 에러가 재발합니다.
4. 코드 해결책
4-1. 임시 해결책 — 실행 JRE를 최신으로 맞추기
에러의 방향은 “클래스 파일 버전 > 실행 JRE"이므로, 실행 환경을 클래스 버전 이상으로 업그레이드하면 즉시 해결됩니다. 배포 대상 서버나 사용자 PC의 자바가 낮다면 아래처럼 자바 전체를 올립니다.
| |
4-2. 권장 해결책 — 컴파일러가 하위 버전 호환 클래스 생성하기
소스가 있다면 실행 대상 JRE 버전에 맞게 컴파일러가 그 이하 버전의 클래스 파일을 만들도록 지시하는 것이 안정적입니다.
JDK 9 이상에서 권장되는 방식은 -release입니다 (bootstrap class path 경고를 피하고 하위 버전 API 제한까지 함께 적용).
| |
-release는 -source/-target과 달리 해당 버전의 API만 보이도록 해서, “컴파일은 됐지만 실행 시 실제로는 없는 API를 호출해 실패"하는 문제까지 막습니다.
4-3. 환경변수(PATH/JAVA_HOME) 통일
여러 JDK/JRE가 깔린 머신이라면 아래로 컴파일/실행이 동일한 버전을 바라보게 합니다.
| |
- Windows라면 시스템 환경변수의
JAVA_HOME과PATH의\bin경로를 같은 버전으로 맞춥니다. - 두 명령의 버전이 다르면 계속 재발하므로 반드시 일치 확인을 거칩니다.
4-4. IDE(Eclipse 등)에서의 설정
Eclipse 프로젝트라면 아래 두 곳이 별개라는 점을 주의합니다.
Window → Preferences → Java → Compiler의 Compiler compliance level 을 실행 JRE 버전으로.- 프로젝트
Properties → Java Build Path → Libraries의 JRE System Library 를 실행 JRE 버전으로. - JAR 라이브러리에서 발생하면 해당 라이브러리 버전을 낮추거나 JRE를 올립니다.
5. 향후 예방 조치
검증 명령
| |
잘못된 해결책 (하지 말 것)
| 오해 | 왜 잘못인가 |
|---|---|
| 무조건 최신 버전만 설치하면 해결된다는 착각 | 실행 환경(서버/PaaS/고객 PC)이 낡은 JRE라면 오히려 반대로 에러가 늘 수 있음 — 타깃 환경 기준으로 판단 |
.class/JAR 파일만 복붙해서 해결하려는 시도 | 클래스 파일의 컴파일 대상 버전은 바뀌지 않으므로 근본 해결이 아님 |
| IDE 컴파일러 compliance만 바꾸고 JRE는 그대로 | Eclipse에서 두 설정이 별개로 존재하므로 Runtime(JRE)도 바꿔야 함 |
실전 적용 체크
| 환경 | 확인 항목 |
|---|---|
| 로컬 | java -version/javac -version 일치, IDE compliance = 실행 JRE |
| CI(빌드) | Maven/Gradle의 자바 툴체인(예: maven.compiler.release) 명시 |
| 프로덕션 | 배포 대상 JRE 버전 ≥ 클래스 파일 major 버전, 컨테이너(Docker) 베이스 이미지 JAVA 버전 확인 |
| 라이브러리 | 외부 JAR의 --release 대상과 실행 JRE 호환성 확인 |
DevTrace verdict: 이 문제의 핵심은 “JAR이 없어서"가 아니라, 컴파일 시 생성된 클래스 파일 major 버전이 실행 JRE가 인식하는 최대 버전보다 높기 때문에 발생하며, JRE 업그레이드 또는
javac --release로 해결해야 한다는 점입니다.
DevTrace 결론
이 에러의 핵심은 컴파일 시 생성된 클래스 파일 버전과 실행 시점의 JRE 버전이 맞지 않는 데 있으며, JRE 업그레이드 또는 javac의 하위 버전 타깃 지정으로 해결합니다.
원문 출처는 문제 발견의 단서이며, 위 판단과 점검 항목은 DevTrace의 독자 분석이다.
출처
- StackOverflow 10382929: How to fix java.lang.UnsupportedClassVersionError: Unsupported major.minor version https://stackoverflow.com/questions/10382929/how-to-fix-java-lang-unsupportedclassversionerror-unsupported-major-minor-versi
- Wikipedia — Java class file (버전 표): https://en.wikipedia.org/wiki/Java_class_file#General_layout
- Oracle — New javac warning for setting an older source without bootclasspath: https://blogs.oracle.com/darcy/entry/bootclasspath_older_source