JDK (Java Development Kit)
개요
JRE (Java Runtime Environment)를 포함하여 컴파일러, 디버거, 프로파일링 도구 등 개발 및 관리에 필요한 도구 모음이다. 컴파일 시점의 JDK 버전과 실행 시점의 JRE 버전이 어긋나면 실무에서 흔히 겪는 버전 호환성 문제로 이어진다.
핵심 개념
- 용어 1: JRE - 자바 애플리케이션을 실행하기 위한 핵심 환경만 포함한다. JVM과 핵심 라이브러리로 구성되며, 컴파일러 같은 개발 도구는 포함하지 않는다.
- 용어 2: 클래스 파일 버전(Major/Minor Version) -
.class파일 헤더에 기록되는 값으로, 어떤 JDK 버전으로 컴파일됐는지를 나타낸다. JVM은 자신이 인식하는 버전보다 높은 클래스 파일을 실행할 수 없어, 이 값이 JDK/JRE 버전 호환성 문제의 실제 판단 기준이 된다.
상세 내용
개발 환경(상위 JDK 컴파일) -> 운영 환경(하위 JRE 실행)
- UnsupportedClassVersionError 발생
- 상위 JDK 컴파일러로 빌드된 .class 파일의 마이너/메이저 버전 번호는 하위 JRE에서 인식하지 못한다. (예: Java 17 JDK로 빌드된 클래스를 Java 11 JRE에서 실행시키면 예외 발생)
- 새로운 API 및 바이트코드 미지원
- 컴파일 시 Target/Release 옵션을 상위로 지정했다면, 하위 JRE 런타임에 존재하지 않는 API를 호출하게 되어 runtime crash가 발생한다.
1 | $ javac --release 17 Main.java # JDK 17로 컴파일 (class file version 61) |
개발 환경(하위 JDK 컴파일) -> 운영 환경(상위 JRE 실행)
| 구분 | 설명 |
|---|---|
| 기본 원칙 | JVM은 하위 호환성을 보장하므로, 낮은 class file version으로 컴파일된 바이트코드는 상위 JRE에서 대체로 문제없이 실행된다. |
| 예외 상황 | 바이트코드 형식 자체는 호환되지만, 컴파일 당시 사용한 API가 상위 버전에서 제거되거나 모듈 경계(JPMS)에 막혀 런타임에 ClassNotFoundException, NoClassDefFoundError가 발생할 수 있다. (예: Java 11부터 javax.xml.bind, java.xml.ws 등 Java EE 관련 모듈이 기본 런타임에서 제거됨) |
| 실무 권장 | 배포 대상 JRE 버전이 다양하다면 "하위 버전은 항상 안전하다"고 단정하기보다, --release 옵션으로 실제 지원해야 하는 가장 낮은 버전을 명시적으로 타깃해 컴파일하는 편이 안전하다. |
정리
Oracle Java 11 이후부터는 독립된 JRE 배포가 중단되었다. 경량화 실행 환경이 필요한 경우 jlink 등을 통해 필요한 모듈만 추출하여 사용자 정의 JRE를 직접 생성하는 방식이 표준이다. 다만 이 글에서 다룬 것처럼 JDK/JRE 버전 호환은 "상위 컴파일 → 하위 실행은 위험, 하위 컴파일 → 상위 실행은 안전"이라는 이분법만으로는 부족하고, 실행 시점에 실제로 필요한 API가 그 버전에 남아있는지까지 함께 확인해야 한다.
댓글



