多版本共存的JAR(Java Archive)文件是Java 9引入的一个新特性,它允许在同一个JAR文件中维护和使用不同版本的Java类或资源。这种特性使得开发者能够创建一个JAR包,该包可以在多个Java版本上运行,而无需为每个Java版本提供单独的JAR包。
接下来这个示例,我们的多版本JAR中有三个版本的MultiJarDemo.java文件,一个用于JDK8,一个用于JDK9,最后一个用于 JDK10,并在可以在这些不同的JDK版本上运行。
准备目录
首先我们准备一个工作目录,我这里叫multi-jar-demo
,目录结构如下:
.
└── src
└── main
├── java10
│ └── com
│ └── morris
│ └── MultiJarDemo.java
├── java8
│ └── com
│ └── morris
│ └── MultiJarDemo.java
└── java9
└── com
└── morris
└── MultiJarDemo.java
java8、java9、java10目录下都一个MultiJarDemo.java,包名也一样。
源码
java8下的MultiJarDemo.java内容如下:
package com.morris;
/**
* 多版本jar,8版本
*/
public class MultiJarDemo {
public static void main(String[] args) {
String javaVersion = System.getProperty("java.version");
System.out.println("JDK version is:" + javaVersion + ", classVersion: 8");
}
}
java9下的MultiJarDemo.java内容如下:
package com.morris;
/**
* 多版本jar,9版本
*/
public class MultiJarDemo {
public static void main(String[] args) {
String javaVersion = System.getProperty("java.version");
System.out.println("JDK version is:" + javaVersion + ", classVersion: 9");
}
}
java10下的MultiJarDemo.java内容如下:
package com.morris;
/**
* 多版本jar,10版本
*/
public class MultiJarDemo {
public static void main(String[] args) {
String javaVersion = System.getProperty("java.version");
System.out.println("JDK version is:" + javaVersion + ", classVersion: 10");
}
}
编译
到multi-jar-demo
目录下,并使用下面的命令编译三个不同版本的class文件,其中,最重要的参数是–release;
$ javac --release 8 -d java8 src/main/java8/com/morris/MultiJarDemo.java
$ javac --release 9 -d java9 src/main/java9/com/morris/MultiJarDemo.java
$ javac --release 10 -d java10 src/main/java10/com/morris/MultiJarDemo.java
--release
选项用于指定要编译目标的JDK版本。
编译完成后就可以看到multi-jar-demo
的目录结构如下:
.
├── java10
│ └── com
│ └── morris
│ └── MultiJarDemo.class
├── java8
│ └── com
│ └── morris
│ └── MultiJarDemo.class
├── java9
│ └── com
│ └── morris
│ └── MultiJarDemo.class
└── src
└── main
├── java10
│ └── com
│ └── morris
│ └── MultiJarDemo.java
├── java8
│ └── com
│ └── morris
│ └── MultiJarDemo.java
└── java9
└── com
└── morris
└── MultiJarDemo.java
20 directories, 6 files
打包
然后我们就可以使用下面的命令将这些不同版本的MultiJarDemo.class封装到一个JAR里。
首先跳转到multi-jar-demo
目录下目录,然后运行下面的命令首先创建一个默认版本,也就是Java8版本;
$ jar -c -f multi-jar-demo.jar --main-class=com.morris.MultiJarDemo -C j
ava8 .
一定要存在一个默认版本,一般情况下,可以使用主流版本为默认版本,这个默认版本可以不用添加–release参数。
运行完成后,就可以在当前目录看到一个multi-jar-demo.jar
文件,我们可以使用jar -tvf multi-jar-demo.jar
来查看文件中的内容:
$ jar -tvf multi-jar-demo.jar
0 Tue Mar 19 11:14:56 CST 2024 META-INF/
103 Tue Mar 19 11:14:56 CST 2024 META-INF/MANIFEST.MF
0 Tue Mar 19 11:01:40 CST 2024 com/
0 Tue Mar 19 11:01:40 CST 2024 com/morris/
727 Tue Mar 19 11:01:40 CST 2024 com/morris/MultiJarDemo.class
然后依次运行下面的命令添加两个其它的版本:
$ jar -u -f multi-jar-demo.jar --release 9 -C java9 .
$ jar -u -f multi-jar-demo.jar --release 10 -C java10 .
好了,这样我们的多版本multi-jar-demo.jar
就已经打包完成了,然后使用jar -tvf multi-jar-demo.jar
来查看文件中最终的内容:
$ jar -tvf multi-jar-demo.jar
0 Tue Mar 19 11:14:56 CST 2024 META-INF/
124 Tue Mar 19 11:25:56 CST 2024 META-INF/MANIFEST.MF
0 Tue Mar 19 11:01:40 CST 2024 com/
0 Tue Mar 19 11:01:40 CST 2024 com/morris/
727 Tue Mar 19 11:01:40 CST 2024 com/morris/MultiJarDemo.class
0 Tue Mar 19 11:06:26 CST 2024 META-INF/versions/10/
0 Tue Mar 19 11:06:26 CST 2024 META-INF/versions/10/com/
0 Tue Mar 19 11:06:26 CST 2024 META-INF/versions/10/com/morris/
959 Tue Mar 19 11:06:26 CST 2024 META-INF/versions/10/com/morris/MultiJarDemo.class
0 Tue Mar 19 11:01:46 CST 2024 META-INF/versions/9/
0 Tue Mar 19 11:01:46 CST 2024 META-INF/versions/9/com/
0 Tue Mar 19 11:01:46 CST 2024 META-INF/versions/9/com/morris/
958 Tue Mar 19 11:01:46 CST 2024 META-INF/versions/9/com/morris/MultiJarDemo.class
运行
在Java10的环境下运行,输出结果如下:
$ java -version
java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)
$ java -jar multi-jar-demo.jar
JDK version is:10.0.2, classVersion: 10
在Java9的环境下运行,输出结果如下:
$ java -version
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
$ java -jar multi-jar-demo.jar
JDK version is:9.0.4, classVersion: 9
在Java8的环境下运行,输出结果如下:
$ java -version
java version "1.8.0_401"
Java(TM) SE Runtime Environment (build 1.8.0_401-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.401-b10, mixed mode)
$ java -jar multi-jar-demo.jar
JDK version is:1.8.0_401, classVersion: 8
最后,尽管多版本共存的JAR为Java应用程序带来了更大的灵活性,但它并不能解决所有版本冲突问题。在某些情况下,你可能需要使用其他工具或策略(如类加载器隔离、OSGi等)来处理复杂的版本冲突问题。