JAVA - java.lang.UnsupportedClassVersionError: Bad version number in .class file 에러 발생

Published on: 2011. 3. 8. 19:55 by louis.dev


위와 같은 Exception으로 검색하면 영문이던 한글이던 솔루션이 많이 나옵니다.

말그대로 .class를 만들때 ( 컴파일 시 ) 컴파일 버전이 달라 에러가 발생하는 것입니다.
예를들어 로컬에서 개발할때 컴파일 버전은 1.6으로 컴파일 했는데, 만약 배포할 서버의 컴파일 버전은 1.5 라면 다음과 같은 에러가 발생합니다.

물론 위와 같은 내용도 인터넷에 깔려 있습니다. 그리고 그 포스팅들의 솔루션은 "컴파일 레벨을 변경하라" 입니다. 

컴파일 레벨은  eclipse의 Window=> Preferences 를 선택하면 나오는 창에서 다음과 같이 컴파일러 레벨을 변경할 수 있습니다.

위와 같은 컴파일 설정은 글로벌한 컴파일 설정이고 각 프로젝트 마다 컴파일 레벨 설정을 하려면
프로젝트 선택 => 오른쪽 마우스 => Properties => Java Complier 에서 변경 할 수 있습니다.

그래서 전 혹시 몰라 두가지 모두 1.6 에서 1.5로 변경하고 서버 배포를 했습니다.

하지만 계속 "Bad version number in .class file" 이라는 에러가 뜨더라구요.

분명히 1.5로 바꿨는데 버전이 안맞는다니..ㅜㅜ

그래서 혹시 몰라 자바 update 버전 까지 맞아야 하나 라는 생각에, oracle사이트에 들어가 자바 업그레이드 버전까지 맞춰 주었지만 같은 문제가 발생했습니다. (결국 삽질이었다는 것을 느꼈죠..;;)

이때부터 패닉상태에 빠져 3시간을 허우적 대다가 같은팀 개발자분에게 도움을 요청한후 해결할 수 있었습니다.

일단. 다음의 코드로 해당 클래스 파일이 올바르게 컴파일 되었는지를 확인합니다.

import java.io.*;

public class Test {
    public static void main(String[] args) throws IOException {
    	checkClassVersion("알고자 하는 .class파일의 경로");
    }                      

    private static void checkClassVersion(String filename)
        throws IOException
    {
        DataInputStream in = new DataInputStream
         (new FileInputStream(filename));

        int magic = in.readInt();
        if(magic != 0xcafebabe) {
          System.out.println(filename + " is not a valid class!");;
        }
        int minor = in.readUnsignedShort();
        int major = in.readUnsignedShort();
        System.out.println(filename + ": " + major + " . " + minor);
        in.close();
    }
}

 이렇게 하시면 현재 컴파일된 class파일의 major와 minor가 나오는데 이를 통해 컴파일 버전을 유추할 수 있습니다.

 MAJOR MINOR  COMPILE VERSION 
 45  3  1.0
 45  3  1.1
 46  0  1.2
 47  0  1.3
 48  0  1.4
 49  0  1.5
 50  0  1.6

저는 위와 같은 코드로 값을 확인해 보니 MAJOR가 50. 즉 컴파일 버전이 1.6으로 자꾸 컴파일이 되는것이었습니다.

이클립스 설정을 통해 분명이 컴파일 레벨을 세팅해 주었음에도 불구하고 어떤 이유에서 인지 1.6으로 컴파일이 되었고 , 그로인해 Bad version number 에러가 발생했던 것이었습니다.

저는 ANT를 통해 컴파일 & 배포를 해왔기 때문에 ANT 컴파일 스크립트에 다음과 같이 추가 해준후 해결할 수 있었습니다.

<target name="02_compile" depends="01_init">
        <javac target="1.5" srcdir="${source}" destdir="${build.classes}" encoding="UTF-8" debug="true" deprecation="true" optimize="true">
        </javac>
</target>


다음과 같이 명시적으로 javac 태그 안에 target으로 컴파일러 버전을 세팅해 준후 배포하니 문제가 해결되었습니다.

무언가 설정이 잘못된 것일 수도 있지만. 무조건 eclipse를 맹신하면 이렇게 삽을 퍼야 하는 상황이 닥칠수 있으니 항상 의심하는 습관을 들여야 겠습니다.ㅜㅜ