Class 파일 JDK 버전 확인

 

JDK Version in Class File

 

Java 프로그램을 개발하다보면 어떤 JDK로 빌드되었는지 확인할 필요가 있다. 다행히도 컴파일된 Class파일이나 컴파일된 Jar파일 안에는 컴파일 할 때 사용했던 JDK 버전에 대한 정보가 포함되어 있기 때문에 확인할 수 있는 방법이 있다. 특히, 다른 사람이 만든 외부 라이브러리를 가져와서 자신의 프로젝트에 포함해서 사용하는 경우에 자주 확인되는 것 같아서, 이번에 JDK를 확인할 수 있는 방법 세가지를 소개한다.

 

JDK를 확인하는 방법을 설명하기 전에, 아래 표 하나만 이해하고 넘어가보겠다. Class 파일 내부에는 컴파일된 JDK 버전이 포함되어 있지만, 이 정보를 확인하면 우리가 보통 사용하는 JDK 버전(ex, 1.8, 1.7)으로 표시된 것이 아니라, 10진수나 16진수로 확인할 수 있다. 따라서 이어서 소개하는 3가지 방법에서 확인된 값을 아래 표와 매칭해서 확인하는 것이 편할 것이다.

 

JDK 10진수(Dec) 16진수(Hex)
..(생략) .. ..
1.8 52 34
1.7 51 33
1.6 50 32
1.5 49 31
1.4 48 30
1.3 47 2F
1.2 46 2E
..(생략) .. ..

 

 

 

방법1. javap 프로그램 사용

PC에 설치된 jdk에 포함되어 있는 javap 프로그램을 사용해서 확인할 수 있다. 현재 개발자가 PC에서 jdk를 어떻게 설정했냐에 따라 경로가 다를 것이므로, 각자 알아서 찾아서 javap를 실행하면 된다. 참고로, 대부분 jdk/bin이 이미 환경변수로 등록되어 있을 것이므로 command 하나를 열어서 바로 실행이 가능할 것이다.

// 사용 방법
$ javap -verbose [class file] | find /N "version" 

// 예시
$ javap -verbose Sample.class | find /N "version" 


출력 :
[6] minor version: 0
[7] major version: 52

위 [예시]처럼 실행하면, [출력] 형태처럼 값을 확인할 수 있을 것이다.  여기서 컴파일된 버전은 major version을 확인하면 된다. 위 Sample.class 파일은 52이므로 JDK 1.8로 컴파일되었다는 의미이다.


 

방법2. Hex 값으로 직접 확인

Hex 값을 읽을 수 있는 에디터(ex, UltraEdit, HxD)로 버전을 확인하려는 Class 파일을 실행시키면 아래처럼 Class 파일에 대한 Hex값이 보일 것이다. 이 값들을 해석하면 JDK 버전을 확인할 수 있다.

 

CA FE BA BE 00 00 00 [JDK version] 00 ...
CA FE BA BE 00 00 00 34 00 ...


Class 파일을 읽으면 앞에서부터 위와 같이 맨 앞에서부터의 값이 "CA FE BA BE 00 00"으로 시작하는 것을 볼 수 있고, 바로 이어지는 다음 1바이트값이 컴파일된 버전을 의미한다. 위 Sample.class 파일은 34인데 이 값은 16진수(Hex)값이므로 이를 10진수로 변경하면 52이다. 따라서 JDK 1.8로 컴파일되었다는 의미이다.


 

방법3. 직접 코딩해서 확인

사실 JDK버전을 확인하기 위해서는 위의 방법1과 방법2로 쉽게 확인할 수 있지만, 혹시 직접 구현중인 프로그램 내에 버전 체크로직을 삽입해야 하는 경우라면 아래처럼 확인해볼 수 있다.

public 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);
	System.out.println(major);
	System.out.println(minor);
	in.close();
}