Java SE 9 多版本兼容 JAR 包示例
Posted 敲代码的老贾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java SE 9 多版本兼容 JAR 包示例相关的知识,希望对你有一定的参考价值。
说明
Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在同一个 Jar 包中我们可以包含多个 Java 版本的 class 文件,这样就能做到 Jar 包升级到新的 Java 版本时不用强迫使用方为了使用新 Jar 包而升级自己的业务模块 Java 版本,也不用针对不同最低支持 Java 版本提供不同的 Jar,真正的做到了一个 Jar 包兼容所有的目的。
本文通过以下示例来说明多版本 Jar 包的使用。
环境准备
机器上应该有多个版本的 JDK 用于测试,并且至少有一个是 JDK 9 或者更高版本。
命令行编译示例
注:本示例无需使用 IDE ,我们用最原始的方式创建一个多版本的 Jar 包。
新建一个文件夹,用项目名称命名,并且在其中把 src
目录,包名都建好,可以自定义,后续编译命令自行调整即可。
src\\main\\java\\git\\snippet
目录下存的是旧版本 JDK 编写的代码。在这个目录下新建两个类。
package git.snippet;
/**
* Java SE 9 Multi-Release JAR Files示例
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/14
* @since
public class App
public static void main(String[] args)
Helper.hello(args[0]);
package git.snippet;
/**
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/14
* @since
public class Helper
public static void hello(String name)
// jdk 9+不能用_作为变量
String _ = "hello";
System.out.println(_ + ", "
src\\main\\java9\\git\\snippet
目录下存的是新版本 JDK 编写的代码。我们需要把 Helper
类用新的 JDK 版本特性来实现。代码如下
package git.snippet;
/**
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/14
* @since
public class Helper
public static void hello(String name)
// 旧版本用_作为变量,jdk9不能用_作为变量
String fixName = "hello";
System.out.println(fixName + ", " + name + " from jdk9");
创建好上述类以后,项目结构如下
接下来是编译,在项目目录下,用 JDK 9+的 javac
执行如下两个编译命令
C:\\jdk\\jdk-11\\bin\\javac --release 7 -d classes src\\main\\java\\git\\snippet\\*.java
提示信息如下(仅显示了警告)
D:\\git\\hello-mrjar>C:\\jdk\\jdk-11\\bin\\javac --release 7 -d classes src\\main\\java\\git\\snippet\\*.java
src\\main\\java\\git\\snippet\\Helper.java:11: 警告: 从发行版 9 开始, _ 为关键字, 不能用作标识符
String _ = "hello";
^
src\\main\\java\\git\\snippet\\Helper.java:12: 警告: 从发行版 9 开始, _ 为关键字, 不能用作标识符
System.out.println(_ + ", " + name);
^
2
C:\\jdk\\jdk-11\\bin\\javac --release 9 -d classes-9 src\\main\\java9\\git\\snippet\\*.java
无提示信息和报错信息。
接下来是通过 JDK 9+ 的 jar
进行打包,打包的时候,运行如下打包命令
C:\\jdk\\jdk-11\\bin\\jar --create --file target/hello-mrjar.jar --main-class git.snippet.App -C classes . --release 9 -C classes-9 .
如果提示如下报错信息
java.nio.file.NoSuchFileException: C:\\Users\\zhuiz\\AppData\\Local\\Temp\\hello-mrjar.jar9462053262887373909.jar -> target\\hello-mrjar.jar
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:395)
at java.base/sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:292)
at java.base/java.nio.file.Files.move(Files.java:1422)
at jdk.jartool/sun.tools.jar.Main.validateAndClose(Main.java:466)
at jdk.jartool/sun.tools.jar.Main.run(Main.java:349)
at jdk.jartool/sun.tools.jar.Main.main(Main.java:1681)
则手动在项目目录下建立一个target文件夹,再次执行打包命令,错误解决。
在 target
目录下,包已经打好 hello-mrjar.jar
。
最后进行测试,用JDK 9之前的 java
来执行这个 jar
包。
C:\\jdk\\jdk1.8\\bin\\java -jar hello-mrjar.jar Grey
输出如下
hello, Grey
用 JDK 9+ 的 java
来执行这个 jar
包。
C:\\jdk\\jdk-11\\bin\\java -jar hello-mrjar.jar Grey
输出如下
hello, Grey from
这样就实现了同一个 Jar 包中包含多个 Java 版本的 class 文件,用不同版本 JDK 执行的时候,运行不同版本的 class 文件。
也可以使用 Intellij IDEA
来创建多版本 Jar,这里是参考文档: Creating Multi-Release JAR Files in IntelliJ IDEA
Maven 项目配合多版本 Jar 示例
多数情况下,我们不会手动创建项目目录并编译,一般用 Maven 来管理项目。本示例演示如何在 Maven 下进行多版本 Jar 包的管理。
创建一个 Maven 项目,结构如下
和上例类似, src\\main\\java9
文件夹中是对应的新版本 JDK 的代码
src\\main\\java
文件夹中是对应的旧版本的 JDK 代码。
代码清单如下
package git.snippet;
public class App
public static void main(String[] args)
System.out.println(String.format("Running on %s", new
旧版本代码,放在 src\\main\\java
对应的包下。
package git.snippet;
public class DefaultVersion
public String version()
System.out.println("use jdk");
return System.getProperty("java.version");
新版本代码,放在 src\\main\\java9
对应的包下。
package git.snippet;
public class DefaultVersion
public String version()
System.out.println("use jdk 9+");
return
pom.xml
文件配置,注意,相关的文件夹或者包有调整,需要做对应的调整。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>git.snippet</groupId>
<artifactId>hello-mrjar-with-maven</artifactId>
<version>1.0</version>
<properties>
<java.version>11</java.version>
<maven.compiler.source>$java.version</maven.compiler.source>
<maven.compiler.target>$java.version</maven.compiler.target>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile-java-8</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compileSourceRoots>
<!---旧版本代码的位置-->
<compileSourceRoot>$project.basedir/src/main/java</compileSourceRoot>
</compileSourceRoots>
</configuration>
</execution>
<execution>
<id>compile-java-9</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
<compileSourceRoots>
<!---新版本代码的位置-->
<compileSourceRoot>$project.basedir/src/main/java9</compileSourceRoot>
</compileSourceRoots>
<outputDirectory>$project.build.outputDirectory/META-INF/versions/9</outputDirectory>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>$maven-jar-plugin.version</version>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
<manifest>
<!--设置主方法入口-->
<mainClass>git.snippet.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
然后用新版本的 JDK 进行打包,在项目目录下执行
mvn clean package -Dmaven.test.skip=true
提示
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ hello-mrjar-with-maven ---
[INFO] Building jar: D:\\git\\hello-mrjar-with-maven\\target\\hello-mrjar-with-maven-1.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.447 s
[INFO] Finished at: 2022-08-15T11:29:48+08:00
说明打包成功。然后进入 target
目录,进行验证
用旧版本的 Java 执行 Jar 包
C:\\jdk\\jdk1.8\\bin\\java -jar hello-mrjar-with-maven-1.0.jar
输出
use jdk
Running on 1.8.0_202
用新版本的 Java 执行 Jar 包
C:\\jdk\\jdk-11\\bin\\java -jar hello-mrjar-with-maven-1.0.jar
输出
use jdk 9+
Running on 11.0.15+8-LTS-149
以上是关于Java SE 9 多版本兼容 JAR 包示例的主要内容,如果未能解决你的问题,请参考以下文章
我一套java代码里既要连接mysql5数据库,又要连mysql8版本,驱动jar包不兼容怎么办?
升级SpringBoot 2.1.X 各jar包冲突、兼容问题