다중 릴리스 JAR(Multi-Release JAR, MRJAR)란?
다중 릴리스 JAR(multi-release jar, 이하 MRJAR)은 하나의 라이브러리 릴리스를 여러 JDK 버전에서 동작할 수 있도록 패키징한 JAR 파일입니다. 즉, JDK 9 환경에서 동작하는 라이브러리를 MRJAR 형태로 만들 수 있으며, MRJAR 내부에는 JDK 9로 컴파일된 클래스 파일이 포함됩니다. 이렇게 JDK 9로 컴파일된 클래스들은 JDK 9에서 새롭게 제공하는 API를 자유롭게 활용할 수 있다는 것이 가장 큰 장점입니다.
기존 방식이라면 구버전 JDK와 호환성을 유지하려면 최신 API를 사용하지 못했지만, MRJAR를 사용하면 하나의 JAR 안에서 구버전용 코드와 신버전용 코드를 함께 제공할 수 있습니다.
MRJAR의 기본 디렉터리 구조
MRJAR는 기존 JAR의 디렉터리 구조를 확장한 형태입니다. 모든 내용물이 위치하는 루트 디렉터리와, JAR에 대한 메타데이터를 저장하는 META-INF 디렉터리로 구성됩니다. 일반적인 JAR에는 속성(attribute) 정보를 담고 있는 META-INF/MANIFEST.MF 파일이 포함됩니다.
기본적인 JAR의 항목 구조는 다음과 같습니다.
- jar-root
- C1.class
- C2.class
- C3.class
- C4.class
- META-INF
- MANIFEST.MF
위 구조에서 JAR는 네 개의 클래스 파일(C1~C4)과 MANIFEST.MF 파일로 이루어져 있습니다.
META-INF/versions 디렉터리의 역할
MRJAR는 특정 JDK 버전 전용 클래스를 저장할 수 있도록 META-INF 디렉터리를 확장합니다. META-INF 디렉터리 안에는 versions라는 하위 디렉터리가 존재하며, 그 아래에 각 JDK 메이저 버전과 동일한 이름을 가진 여러 하위 디렉터리가 배치됩니다.
- JDK 9 전용 클래스 →
META-INF/versions/9디렉터리 - JDK 10 전용 클래스 →
META-INF/versions/10디렉터리
- jar-root
- C1.class
- C2.class
- C3.class
- C4.class
- META-INF
- MANIFEST.MF
- versions
- 9
- C2.class
- C5.class
- 10
- C1.class
- C2.class
- C6.class
MRJAR의 동작 방식
MRJAR가 실제로 동작하려면 MANIFEST.MF 파일에 반드시 Multi-Release: true 속성을 선언해야 합니다. 이 속성이 있어야 JVM이 해당 JAR를 다중 릴리스 JAR로 인식합니다.
실행 시점의 동작은 다음과 같습니다.
- JDK 9 이상: 루트의 클래스보다
META-INF/versions/<버전>디렉터리에 있는 클래스가 우선적으로 로드됩니다. 예를 들어 JDK 9 환경에서는 versions/9의 C2.class가 루트의 C2.class보다 우선합니다. - JDK 8 이하: versions 디렉터리를 단순히 무시하고 루트 디렉터리의 클래스만 사용하므로, 구버전 환경에서도 문제없이 동작합니다.
이처럼 MRJAR를 활용하면 하나의 아티팩트로 구버전과 신버전 JDK를 모두 지원할 수 있어, 라이브러리 배포와 버전 관리가 훨씬 간편해집니다.