수색…


소개

Java 9에 도입 된 기능 중 하나는 동일한 Jar 파일에서 여러 Java 릴리스를 대상으로 코드를 번들로 묶을 수있는 다중 릴리스 Jar (MRJAR)입니다. 이 기능은 JEP 238에 명시되어 있습니다.

다중 릴리스 Jar 파일의 내용 예

MANIFEST.MF 파일에서 Multi-Release: true 를 설정하면 Jar 파일이 다중 릴리스 Jar가되고 Java 런타임 (MRJAR 형식을 지원하는 한)이 현재 주요 버전에 따라 적절한 버전의 클래스를 선택합니다 .

이러한 Jar의 구조는 다음과 같습니다.

jar root
  - A.class
  - B.class
  - C.class
  - D.class
  - META-INF
     - versions
        - 9
           - A.class
           - B.class
        - 10
           - A.class
  • JDK <9에서는 루트 항목의 클래스 만 Java 런타임에서 볼 수 있습니다.
  • JDK 9에서는 클래스 A와 B가 root/META-INF/versions/9 디렉토리에서로드되고 C와 D는 기본 항목에서로드됩니다.
  • JDK 10에서 클래스 A는 root/META-INF/versions/10 디렉토리에서로드됩니다.

jar 도구를 사용하여 다중 릴리스 Jar 만들기

jar 명령은 클래스가 동일하다는 경고와 함께 Java 8 및 Java 9 용으로 컴파일 된 동일한 클래스의 두 버전을 포함하는 다중 릴리스 Jar를 작성하는 데 사용할 수 있습니다.

C:\Users\manouti>jar --create --file MR.jar -C sampleproject-base demo --release 9 -C sampleproject-9 demo
Warning: entry META-INF/versions/9/demo/SampleClass.class contains a class that
is identical to an entry already in the jar

--release 9 옵션은 sampleproject-9 의 버전이 지정된 항목, 즉 root/META-INF/versions/9 아래에 jar 가 따르는 모든 내용 ( sampleproject-9 디렉토리의 demo 패키지)을 포함하도록 지시합니다. 결과는 다음 내용입니다.

jar root
  - demo
     - SampleClass.class
  - META-INF
     - versions
        - 9
           - demo
              - SampleClass.class

이제 SampleClass 의 URL을 인쇄하고 Java 9 버전에 추가하는 Main이라는 클래스를 만듭니다.

package demo;

import java.net.URL;

public class Main {

    public static void main(String[] args) throws Exception {
        URL url = Main.class.getClassLoader().getResource("demo/SampleClass.class");
        System.out.println(url);
    }
}

이 클래스를 컴파일하고 jar 명령을 다시 실행하면 오류가 발생합니다.

C:\Users\manouti>jar --create --file MR.jar -C sampleproject-base demo --release 9 -C sampleproject-9 demoentry: META-INF/versions/9/demo/Main.class, contains a new public class not found in base entries
Warning: entry META-INF/versions/9/demo/Main.java, multiple resources with same name
Warning: entry META-INF/versions/9/demo/SampleClass.class contains a class that
is identical to an entry already in the jar
invalid multi-release jar file MR.jar deleted

그 이유는 jar 도구가 기본 항목에 추가되지 않으면 공용 클래스를 버전이 지정된 항목에 추가하지 못하게하기 때문입니다. 이는 MRJAR이 다른 Java 버전에 대해 동일한 공개 API를 제공하도록 수행됩니다. 런타임에는이 규칙이 필요하지 않습니다. jar 같은 도구로만 적용 할 수 있습니다. 이 특별한 경우, Main 의 목적은 샘플 코드를 실행하는 것이므로 기본 항목에 복사본을 추가하기 만하면됩니다. 클래스가 Java 9에만 필요한 새로운 구현의 일부라면 비공개로 만들 수 있습니다.

루트 항목에 Main 을 추가하려면 먼저 Java 9 이전 버전을 대상으로 Main 을 컴파일해야합니다. 이것은 javac 의 새로운 --release 옵션을 사용하여 수행 할 수 있습니다.

C:\Users\manouti\sampleproject-base\demo>javac --release 8 Main.java
C:\Users\manouti\sampleproject-base\demo>cd ../..
C:\Users\manouti>jar --create --file MR.jar -C sampleproject-base demo --release 9 -C sampleproject-9 demo

Main 클래스를 실행하면 SampleClass가 버전이 지정된 디렉토리에서로드됩니다.

C:\Users\manouti>java --class-path MR.jar demo.Main
jar:file:/C:/Users/manouti/MR.jar!/META-INF/versions/9/demo/SampleClass.class

다중 릴리스 Jar 내의로드 된 클래스의 URL

주어진 다중 릴리스 Jar :

jar root
  - demo
     - SampleClass.class
  - META-INF
     - versions
        - 9
           - demo
              - SampleClass.class

다음 클래스는 SampleClass 의 URL을 인쇄합니다.

package demo;

import java.net.URL;

public class Main {

    public static void main(String[] args) throws Exception {
        URL url = Main.class.getClassLoader().getResource("demo/SampleClass.class");
        System.out.println(url);
    }
}

클래스가 컴파일되어 MRJAR의 Java 9 용 버전이 지정된 항목에 추가되면이를 실행하면 다음과 같은 결과가 발생합니다.

C:\Users\manouti>java --class-path MR.jar demo.Main
jar:file:/C:/Users/manouti/MR.jar!/META-INF/versions/9/demo/SampleClass.class


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow