表明Java9版本增强了Jar包多版本字节码文件格式支持,也就是说我们可以在同一个Jar中包含多个Java版本类文件包裹。这样,当Jar包升级到新的Java版本时,不需要强制用户升级自己的业务模块Java版本来使用新的Jar包,也不需要提供不同的Jar对于不同的最低支持的Java版本。Jar包兼容所有用途。本文通过以下示例来说明多版本Jar包的使用。用于测试的环境准备机器上应该有多个版本的JDK,其中至少有一个是JDK9或更高版本。命令行编译示例注意:本示例不需要使用IDE,我们使用最原始的方式创建多版本Jar包。新建一个文件夹,以工程名命名,并在里面创建src目录和包名,可以自定义,后面的编译命令自行调整。src\main\java\git\snippet目录下存放的是老版本JDK编写的代码。在此目录中创建两个新类。packagegit.snippet;/***JavaSE9多版本JAR文件示例**@author灰色*@date2022/8/14*@since9*/publicclassApp{publicstaticvoidmain(String[]args){Helper.hello(args[0]);}}packagegit.snippet;/***@author灰色*@date2022/8/14*@since1.7*/publicclassHelper{publicstaticvoidhello(Stringname){//jdk9+不能使用_作为变量String_="hello";System.out.println(_+","+名字);}}src\main\java9\git\snippet目录下存放新版JDK编写的代码。我们需要实现具有新JDK版本功能的Helper类。代码如下packagegit.snippet;/***@author灰色*@date2022/8/14*@since9*/publicclassHelper{publicstaticvoidhello(Stringname){//旧版本使用_作为变量,jdk9不能使用_作为变量StringfixName="hello";System.out.println(fixName+","+name+"fromjdk9");}}创建以上类后,项目结构如下。接下来是编译。在项目目录下,使用JDK9+的javac执行如下两条编译命令:C:\jdk\jdk-11\bin\javac--release7-dclassessrc\main\java\git\snippet\*。java提示信息如下(只显示警告)D:\git\hello-mrjar>C:\jdk\jdk-11\bin\javac--release7-dclassessrc\main\java\git\snippet\*.javasrc\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--release9-dclasses-9src\main\java9\git\snippet\*.java没有提示信息和错误信息接下来就是通过JDK9+的jar进行打包。打包时运行如下打包命令C:\jdk\jdk-11\bin\jar--create--filetarget/hello-mrjar.jar--main-classgit.snippet.App-Cclasses。--release9-Cclasses-9。如果出现如下错误信息java.nio.file.NoSuchFileException:C:\Users\zhuiz\AppData\Local\Temp\hello-mrjar.jar9462053262887373909提示.jar->target\hello-mrjar.jaratjava.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)在java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)在java.base/sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:395)在java.base/sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:292)在java.base/java.nio.file.Files.move(Files.java:1422)jdk.jartool/sun.tools.jar.Main.validateAndClose(Main.java:466)在jdk.jartool/sun.tools.jar.Main。run(Main.java:349)atjdk.jartool/sun.tools.jar.Main.main(Main.java:1681)在项目目录下手动创建一个target文件文件夹,再次执行打包命令,在target目录下报错解决,包已经打包好了hello-mrjar.jar。最后为了测试,使用JDK9之前的java执行jar包。C:\jdk\jdk1.8\bin\java-jarhello-mrjar.jarGray输出如下hello,Gray使用JDK9+java执行这个jar包。C:\jdk\jdk-11\bin\java-jarhello-mrjar.jarGray输出如下hello,Grayfromjdk9,这样同一个Jar包中包含多个Java版本的class文件,用不同的版本执行JDK运行不同版本的类文件时。也可以使用IntellijIDEA创建多版本Jar,参考文档:CreatingMulti-ReleaseJARFilesinIntelliJIDEAMavenprojectwithmulti-versionJarexample大多数情况下,我们不会手动创建项目目录和编译it,一般用Maven来管理it项目。本示例演示如何在Maven下管理多版本Jar包。创建一个Maven项目,其结构与上述示例类似。src\main\java9文件夹包含对应新版本JDK的代码,src\main\java文件夹包含对应旧版本JDK的代码。代码清单如下packagegit.snippet;publicclassApp{publicstaticvoidmain(String[]args){System.out.println(String.format("Runningon%s",newDefaultVersion().version()));}}老版本代码,放在src\main\java对应的包下。包git.snippet;publicclassDefaultVersion{publicStringversion(){System.out.println("usejdk");返回System.getProperty("java.version");}}新版本代码,放在src\main对应\java9的包下。packagegit.snippet;publicclassDefaultVersion{publicStringversion(){System.out.println("使用jdk9+");返回Runtime.version().toString();}}pom.xml文件配置,注意,相关文件夹或包已经调整,需要做相应调整。4.0.0git.snippethello-mrjar-with-maven1.011${java.version}${java.version}3.2.0org.apache.maven.pluginsmaven-compiler-plugincompile-java-8编译1.81.8${project.basedir}/src/main/javacompile-java-9compilecompile9${project.basedir}/src/main/java9${project.build.outputDirectory}/META-INF/versions/9default-testCompiletest-compiletestCompiletrueorg.apache.maven.pluginsmaven-jar-plugin${maven-jar-plugin.version}truegit.snippet.App然后使用新版本打包JDK,在项目目录提示[INFO]中执行mvncleanpackage-Dmaven.test.skip=true---maven-jar-plugin:3.2.0:jar(default-jar)@hello-mrjar-with-maven---[INFO]构建jar:D:\git\hello-mrjar-with-maven\target\hello-mrjar-with-maven-1.0.jar[INFO]----------------------------------------------------------------------[信息]构建成功[信息]---------------------------------------------------------------------[信息]总时间:1.447s[信息]完成于:2022-08-15T11:29:48+08:00[信息]-----------------------------------------------------------------------表示包装是成功的然后进入目标目录验证,使用老版本的Java执行Jar包C:\jdk\jdk1.8\bin\java-jarhello-mrjar-with-maven-1.0.jaroutputusejdkRunningon1.8。0_202与新版本Java执行Jar包C:\jdk\jdk-11\bin\java-jarhello-mrjar-with-maven-1.0.jaroutputusejdk9+Runningon11.0.15+8-LTS-149