Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

UnsupportedClassVersionError? Java를 바꾸기 전에 클래스와 로딩 JVM을 증명하세요

오류는 호환성 불일치의 양쪽을 알려 줍니다. 클래스 major, artifact와 실제 launcher를 보존하고 runtime을 올릴지 build를 retarget할지 선택한 뒤 오래된 출력을 지우고 local, CI, production 유사 진입점에서 같은 artifact를 검증하세요.

Java class-file과 runtime 경계 도식
원본 일러스트: 거부된 artifact와 실제로 로드하는 JVM을 연결합니다. Watch at Ease

오류는 호환성 불일치의 양쪽을 알려 줍니다. 클래스 major, artifact와 실제 launcher를 보존하고 runtime을 올릴지 build를 retarget할지 선택한 뒤 오래된 출력을 지우고 local, CI, production 유사 진입점에서 같은 artifact를 검증하세요.

JVM은 지원하는 class-file version만 로드하며 더 높은 major는 애플리케이션 실행 전에 거부됩니다. Java 8부터 Java 25는 class-file major 52부터 69에 대응합니다.

1. 정확한 불일치를 고정하세요

첫 UnsupportedClassVersionError 전체, 거부된 class, 보고된 class-file version, 인식 상한, launcher command와 시간을 보존합니다. 나중에 연 다른 shell이 아니라 실패 context의 java -version과 javac -version을 기록하세요.

JVM 명세로 두 major를 해석하되 표에서 멈추지 마세요. 일반 major mismatch와 minor 65535 preview mismatch는 요구사항이 다르므로 노출되면 둘 다 기록합니다.

2. 거부된 artifact를 식별하세요

첫 stack frame의 정확한 .class나 JAR을 찾아 path, hash, package 좌표나 image digest와 build provenance를 기록합니다. 가능하면 추출한 class에 javap -verbose를 사용해 실행하지 않고 major를 확인합니다.

거부 class가 application, build plugin, annotation processor, IDE helper 또는 transitive dependency인지 구분합니다. application target 변경으로 이미 배포된 third-party bytecode는 바뀌지 않습니다.

3. 실제 로딩 runtime을 증명하세요

실제로 class를 로드하는 process의 java path, command line, JAVA_HOME/toolchain, working directory와 container image를 추적합니다. service는 unit, CI는 runner step, IDE와 daemon은 재시작 후 설정을 확인합니다.

login shell의 which java만 증거로 삼지 마세요. wrapper, SDK manager, symlink, daemon reuse, PATH 순서와 container layer가 다른 JVM을 선택할 수 있습니다.

4. 호환 방향 하나를 선택하세요

새 bytecode가 필요하고 dependency가 지원하면 소유 launcher의 runtime을 올리고 support window를 확인합니다. 개발 shell만이 아니라 service, CI image, IDE, container를 바꾸고 persistent daemon을 재시작합니다.

오래된 runtime을 유지해야 하면 --release 등으로 통제 가능한 코드를 retarget하고 호환 bytecode를 배포하는 dependency/plugin version을 선택합니다. class header 수정이나 source 호환 추측은 피합니다.

5. 오래되고 섞인 출력을 제거하세요

새 class가 남을 수 있는 output, cache와 package를 삭제하거나 격리합니다. 선택한 toolchain으로 clean build하고 artifact hash를 기록해 application, generated, dependency class를 대표 확인합니다.

multi-module에서는 한 module, 생성 task 또는 plugin이 다른 JDK를 쓸 수 있습니다. compile 성공만 믿지 말고 build log, toolchain 선택과 최종 package를 증명합니다.

6. 모든 실제 진입점을 검증하세요

같은 artifact hash를 필요한 shell, IDE/build tool, CI, service와 production 유사 container에서 실행합니다. 첫 class가 로드되고 테스트가 통과하며 뒤에 다른 불일치 class가 없어야 합니다.

launcher, java path, runtime version, artifact hash, class major, 결과와 rollback을 표로 남깁니다. 하나의 호환 정책이 build와 loader를 함께 통제해야 완료입니다.

Java 호환성 복구 매트릭스
원본 일러스트: runtime 업그레이드 또는 build retarget 후 모두 검증합니다. Watch at Ease