文章

Multi-Release JARs (MRJARs) 多 Java 环境适配

Java 9 的新特性 JEP 238: Multi-Release JAR Files 允许为适配不同 Java 版本的环境,给同一个类或方法编写不同版本的代码,以供不同运行时使用。

例如,在项目中为 Java 8(默认)与 Java 17 配置并编写了两种代码。当在 >= Java 17 的环境中运行时,就会默认执行 Java 17 的代码。


Multi-Release JAR Files 首先需要在 MANIFEST.MF 中声名:

1
Multi-Release: true

并为不同的 Java 版本,提供不同的代码,目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hony@macbook project % tree
.
├── META-INF
│   └── MANIFEST.MF
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── github
        │           └── h0ny
        │               ├── Main.java
        │               └── Utils.java
        ├── java17
        │   └── com
        │       └── github
        │           └── h0ny
        │               └── Utils.java
        └── resources

Maven 适配多个版本 Java 环境配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.13.0</version>
    <configuration>
        <release>8</release>
        <source>8</source>
        <target>8</target>
    </configuration>
    <executions>
        <!-- Default execution for Java 8 -->
        <execution>
            <id>default-compile</id>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
        <!-- Additional execution for Java 17 -->
        <execution>
            <id>compile-java-17</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <release>17</release>
                <compileSourceRoots>
                    <compileSourceRoot>${project.basedir}/src/main/java17</compileSourceRoot>
                </compileSourceRoots>
                <multiReleaseOutput>true</multiReleaseOutput>
                <!-- <outputDirectory>${project.build.outputDirectory}/META-INF/versions/17</outputDirectory> -->
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.4.2</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Multi-Release>true</Multi-Release>
                <Main-Class>com.github.h0ny.Main</Main-Class>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

检查并运行,查看效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
hony@macbook project % jenv shell 1.8
hony@macbook project % mvn package
...

hony@macbook project % jar --list --file target/project-1.0-SNAPSHOT.jar
hony@macbook project % jar -xf target/project-1.0-SNAPSHOT META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF
...

hony@macbook project % java -jar target/project-1.0-SNAPSHOT.jar
JDK 8 编译

hony@macbook project % jenv shell 22
hony@macbook project % java -jar target/project-1.0-SNAPSHOT.jar
JDK 17 编译

参考文章:

  • https://blog.gradle.org/mrjars
  • https://www.baeldung.com/maven-multi-release-jars
  • https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html
本文由作者按照 CC BY 4.0 进行授权

© h0ny. 保留部分权利。

本站由 Jekyll 生成,采用 Chirpy 主题。