Java 简明教程

Java - Multi-Release Jar Files

Multi-release JAR 功能是在 Java 9 中引入的。它允许使用与多个 Java 版本相关的多个类版本。例如,许多第三方库或框架使用 Java。由于 Java 作为一门语言在不断发展,并且在每次重大版本发布时,都会为该语言添加许多新功能。由于第三方库/框架必须重写其代码库才能适应新功能,因此团队非常不愿意使用新功能。它阻碍了它们向新的 versions of Java 迁移。

为了解决同一文件或平台特定文件版本的多个源代码的此维护问题,引入了多版本 JAR 特性。考虑以下示例:

典型的 jar 文件在根级别具有所有类。

jar root
   - Calculator.class
   - Util.class
   - Math.class
   - Service.class

如果我们具有 Java 9 特定功能 Util class ,则无法在 JRE 8 或更低版本中使用该 jar。

在多发布 JAR 中,格式得到了增强,能够存储不同的 Java classes 版本或资源,可以根据平台进行维护和使用。在 JAR 中,一个文件 MANIFEST.MF 文件在其主部分有一个条目 Multi-Release: true。META-INF 目录还包含一个版本子目录,其子目录(从 Java 9 的 9 开始)存储特定于版本的类和资源文件。

使用 MANIFEST.MF,我们可以在单独的位置指定 Java 9 或更高版本的特定类,如下所示:

Java Multi-Release Jar Files Directory Structure

jar root
   - Calculator.class
   - Util.class
   - Math.class
   - Service.class
   META-INF
      - versions
      - 9
         - Util.class
         - Math.class
      - 10
         - Util.class
         - Math.class

现在,如果 JRE 不支持多发行 JAR,那么它将选择根级别类进行加载和执行,否则,将加载特定于版本的类。例如,如果在 Java 8 中使用了上述 JAR,那么将使用根级别的 Util.class。如果 Java 9 执行了相同的 JAR,那么将选择特定于 Java 9 版本的类,依此类推。通过这种方式,第三方库/框架可以在不更改针对较低版本编写的源代码的情况下支持新特性。

Creating and Using Multi-Release Jar Files in Java

在此示例中,我们将创建并使用多版本 jar 来拥有两个版本的 Tester.java 文件,一个用于 jdk 7,一个用于 jdk 9,并在不同 jdk 版本上运行它。

以下是有关在 Java 中创建和使用多版本 jar 文件的步骤 -

Step 1: Create Java 7 Specific Java Class

让我们创建一个 Java 类,它可能具有 Java 7 特定的代码和特性,在 Java 9 之前不可用。在此示例中,我们仅打印一条消息,以展示此特性的用法。

创建一个文件夹 c:/test/java7/com/tutorialspoint。使用以下内容创建 Tester.java −

Tester.java

这是一段简单的代码,在我们执行程序时,会打印一个 Java 7 特定的消息。

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 7");
   }
}

Step 2: Create Java 9 Specific Java Class

让我们创建一个 Java 类,它可能具有 Java 9 增强特性和特性,在 Java 9 之前不可用。在此示例中,我们仅打印一条消息,以展示此特性的用法。

创建一个文件夹 c:/test/java9/com/tutorialspoint。使用以下内容创建 Tester.java −

Tester.java

这也是类似于上面的代码,在执行程序时会打印一个 Java 9 特定的消息。

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 9");
   }
}

为了使用多发布 jar 功能,我们必须确保两个类的签名相同。公共 interface ,如方法签名,在两个类中应该相同。

Step 3: Compile with Target Versions

C:\test > javac --release 9 java9/com/tutorialspoint/Tester.java

C:\JAVA > javac --release 7 java7/com/tutorialspoint/Tester.java

Step 4: Create a Multi-Release JAR

C:\JAVA > jar -c -f test.jar -C java7 . --release 9 -C java9.
Warning: entry META-INF/versions/9/com/tutorialspoint/Tester.java,
   multiple resources with same name

Step 5: Run the JAR with JDK 7

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 7

Step 6: Run the JAR JDK 9

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 9

Conclusion

我们看到,使用多版本 Jar 特性,我们可以创建多个类版本而无需担心向后兼容性问题。我们展示了相同的命令可用于执行类。根据 META-INF 文件中列出的 JRE 版本,选择相应的类。对于不支持多版本 jar 的较低 JRE 版本,则选择根级别类而不是特定于版本的类。最后,带版本类的公共方法的签名应相同,这样此功能才能完美运行。