Java 9中的Multi-Release jar「mrjar」是什么?

1. Multi-Release jar概述

Java 9中提供了一个名为Multi-Release jar(mrjar)的新功能,它能够使得一个jar包中包含多个版本的class文件,使得一个jar包能够在不同版本的JRE上使用。这样做的好处在于,能够让程序在运行时自动根据当前的JRE版本选择最适合的class文件。同时,这也能够让开发者在使用新版本的Java API时,不必担心向下兼容性问题。

2. Multi-Release jar的工作原理

2.1 jar文件结构

一个普通的jar包的目录结构如下:

jarFile.jar

└── com

└── example

└── MyClass.class

其中MyClass.class是一个针对JRE版本A编译的版本,该版本的class文件不能在低于JRE版本A的环境中使用。如果我们在低于JRE版本A的环境中运行jarFile.jar,则会出现异常。

而在Multi-Release jar中,我们可以在jar包中提供多个版本的class文件,如下:

jarFile.jar

├── com

│ └── example

│ ├── MyClass.class

│ └── MyClass.class // 针对JRE版本B的新版本

└── META-INF

└── versions

├── 9

│ └── com

│ └── example

│ ├── MyClass.class // 针对JRE版本9的新版本

│ └── MyNewClass.class // 针对JRE版本9的全新class文件

└── 10

└── com

└── example

└── MyClass.class // 针对JRE版本10的新版本

上述目录结构中,我们为各个版本的class文件制定了特定的目录。其中,版本9和版本10的目录中存放的是对应的JRE版本所需要的class文件,而根目录和通用版本的目录中,我们存放了针对低版本JRE的class文件。

2.2 MANIFEST.MF文件

除了上述的目录结构外,Multi-Release jar还需要在MANIFEST.MF文件中声明自己是一个Multi-Release jar,并指定默认版本的目录,如下所示:

Manifest-Version: 1.0

Multi-Release: true

Main-Class: com.example.Main

2.3 运行时选择版本

当我们在运行Multi-Release jar时,Java虚拟机会根据当前运行环境的版本自动选择相应的class文件。如果当前运行的是针对版本B的JRE,则会选择通用版本的class文件。如果当前运行的是针对JRE版本9的JRE,则会选择versions/9目录下的class文件。

3. 使用Multi-Release jar

3.1 创建Multi-Release jar包

创建Multi-Release jar包比普通的jar包要复杂一些。需要手动组织目录结构和MANIFEST.MF文件。我们可以使用以下命令来创建一个Multi-Release jar包:

jar -c -v -f demo.mrjar -m META-INF/MANIFEST.MF -C classes .

jar -u -v --release 9 -f demo.mrjar -C classes/java9 .

上述命令中,第一条命令会创建一个普通的jar包,其中包含java8版本的class文件。第二条命令会向jar包中添加针对Java 9的class文件,这些文件会被存放在META-INF/versions/9目录下。这里的--release 9表示我们添加的class文件是针对Java 9版本的。

3.2 使用Multi-Release jar包

使用Multi-Release jar包与使用普通的jar包类似,只是需要在启动时指定-jar参数,并保证使用的JRE版本高于或等于该jar包中针对的最高版本。例如:

java -jar demo.mrjar

如果当前环境的JRE版本低于该jar包中指定的最高版本,则会报错。

4. 总结

Java 9中提供的Multi-Release jar是一个非常实用的功能,它能够让一个jar包同时适用于多个JRE版本,并且能够自动切换使用哪个版本的class文件。这对于使用新版本Java API的开发者来说,能够带来非常大的便利。不过,使用Multi-Release jar也需要注意一些问题,例如确保目录结构正确,以及保证使用的JRE版本高于或等于该jar包中针对的最高版本。

后端开发标签