Java SE 9 多版本兼容 JAR 包示例

目录
  • 说明
  • 环境准备
  • 命令行编译示例
  • Maven 项目配合多版本 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" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Grey</a>
 * @date 2022/8/14
 * @since 9
 */
public class App {
    public static void main(String[] args) {
        Helper.hello(args[0]);
    }
}
package git.snippet;

/**
 * @author <a href="mailto:410486047@qq.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Grey</a>
 * @date 2022/8/14
 * @since 1.7
 */
public class Helper {
    public static void hello(String name) {
        // jdk 9+不能用_作为变量
        String _ = "hello";
        System.out.println(_ + ", " + name);
    }
}

src\main\java9\git\snippet 目录下存的是新版本 JDK 编写的代码。我们需要把 Helper 类用新的 JDK 版本特性来实现。代码如下

package git.snippet;

/**
 * @author <a href="mailto:410486047@qq.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >Grey</a>
 * @date 2022/8/14
 * @since 9
 */
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 jdk9

这样就实现了同一个 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 DefaultVersion().version()));
    }
}

旧版本代码,放在 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 Runtime.version().toString();
    }
}

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
[INFO] ------------------------------------------------------------------------

说明打包成功。然后进入 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 JAR 包内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java RSA加密解密实现方法分析【附BASE64 jar包下载】

    本文实例讲述了Java RSA加密解密实现方法.分享给大家供大家参考,具体如下: 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar javabase64-1.3.1.jar 本站下载地址. 注意: RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行. RSA加密对明文的长度是有限制的,如果加密数据过大会抛出如下异常: Exception in thread "main" javax.cryp

  • Eclipse 导出可执行Java工程/可执行Jar文件(包含第三方Jar包)

    Eclipse导出可执行Java工程/可执行Jar文件(包含第三方Jar包) 师兄部署了新的虚拟机,新学期大搞起来!之前由于爬虫代码不稳定,所以一直都是直接用Eclipse运行,然后遇到问题就修改的.但是这个比较麻烦,而且Eclipse本身就很占内存啊,摔!所以今天下午就把之前的代码清减了一下,对很多挫挫的System.out.println替换了log4j,路径啊数据库连接呀用配置文件处理了,最后打成可执行的Jar,这样在新的虚机上就可以大展拳脚咯^_^Y Biu~废话说完,进入正题,将Jav

  • IntelliJ IDEA里找不到javax.servlet的jar包的解决方法

    今天在复习Java Web时,因为初次使用 IntelliJ IDEA 中, 当使用javax.servlet包下的类时(例:javax.servlet.http.HttpServletRequest), 你会发现在IntelliJ IDEA里无法成功编译这个程序. 问题解决: 办法1:使用Project Structure 在弹出的窗口中选择tomcat所在的目录,进入里面的lib目录,寻找servlet-api.jar这个jar包(如果JSP页面也有相关的JavaWeb对象,则还要寻找jsp

  • 在eclipse导入Java的jar包的方法JDBC(图文说明)

    在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 打开eclipse 1.右击要导入jar包的项目,点properties  2.左边选择java build path,右边选择libraries  3.选择add External jars  4.选择jar包的按照路径下的 确定后就行了. Java连接MySQL的最新驱动包下载地址 http://www.mysql.com/downloads/connector/j 有两种方法导入jar包

  • 用Java连接sqlserver数据库时候几个jar包的区别分析

    今天在群里看见有人问了这个问题,那就把我自己总结的知识拿出来与大家分享一下吧..当然可能还有什么不对的地方,希望指出: ***msbase.jar.mssqlserver.jar.msutil.jar(支持sql2000): 早期的连接数据库Jar包:在连接数据时候需要手动导入驱动包.即手动导入class.forName(驱动名称); ***SQL Server JDBC Driver 2.0----sqljdbc.jar和sqljdbc4.jar 新版JDBC连接数据库Jar包,支持sql20

  • Eclipse创建java程序可执行jar包教程

    一.eclipse中,在要打成jar包的项目名上右击,出现如下弹出框,选择"export": 二.在接下来出现的界面中点击"jar file",然后next: 三.在接下来出现的界面中,如图所示勾选上要打包的项目以及其他选项,例如test项目:然后点击右边箭头所指的browse,选择打好的jar包要保存的目录,同时给自己的jar包命名,例如我这里选择存放在桌面,名字为jarTest;然后点击"next",在之后弹出的界面中再点击一次"n

  • Java SE 9 多版本兼容 JAR 包示例

    目录 说明 环境准备 命令行编译示例 Maven 项目配合多版本 Jar 示例 说明 Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在同一个 Jar 包中我们可以包含多个 Java 版本的 class 文件,这样就能做到 Jar 包升级到新的 Java 版本时不用强迫使用方为了使用新 Jar 包而升级自己的业务模块 Java 版本,也不用针对不同最低支持 Java 版本提供不同的 Jar,真正的做到了一个 Jar 包兼容所有的目的. 本文通过以下示例来说明多版本 Jar

  • 用命令行编译java并生成可执行的jar包方法

    1.编写源代码 编写源文件:CardLayoutDemo.java并保存,例如:I:\myApp\CardLayoutDemo.java.程序结构如下: package test; import java.awt.*; import javax.swing.*; //更多包的导入... class NotePadFrame extends JFrame { //主界面的设计... } //其他相关代码... public class CardLayoutDemo { public static

  • 浅谈java项目与javaweb项目导入jar包的区别

    现在的项目基本上都是java web项目,所以导入jar包会出现问题,主要介绍一下java项目与javaweb项目的区别: java项目: 在classLoader加载jar和class的时候,是分开加载的,一般jar导入分两种: 1.在web-inf下的lib中直接引入 2.在user library上引入 无论以上哪种引入,jar包都能加载并且运行,classLoader会智能加载(本地JRE运行) javaweb项目: 不是通过本地的JRE运行的,而是部署到web服务器(比如tomcat,

  • idea打包java程序(包含依赖的所有jar包)

    Intellij Idea打包Java项目 打开模块设置 如下图所示,选中需要打包的模块,右键点击,即会出现如下图所示的内容,点击Open Module Settings. 创建Artifacts 配置Jar包信息 注意配置输出路径 Output directory: 移动依赖Jar包到指定文件夹中并配置路径 如下图所示,将项目依赖的Mysql驱动包移动到library文件夹中.方法是只需要在上右键点击创建文件夹,然后将第三方的Jar包拖动进入此文件夹即可. 并且点击图中马赛克部分的那个Jar文

  • 如何将java或javaweb项目打包为jar包或war包

    目录 一.为什么打包 二.如何打包 1.打成jar包 1.1.使用jar手动打包 1. 2.使用IDEA进行打包 2.打成war包 一.为什么打包 关于此问题,网上众说纷纭.结合个人理解以及网上说法,打成jar包是为了方便别人使用. 如果是运行java程序,就不需要在寻找包含main方法的类去执行:如果是使用第三方jar包,直接在自己项目中导入jar包,而不是复制一堆类文件.打成war包是真实生产环境选择的web应用部署方式,网上说这样不会像直接复制文件夹那样可能造成文件丢失,而且服务器会对应用

  • Java SE求解汉诺塔问题的示例代码

    目录 1.问题描述 2.画图分析 3.问题讲解 4.代码实现 1.问题描述 汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说. 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘. 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上. 并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘. 问应该如何操作? 2.画图分析 一个圆盘的情况:移动前 移动后 1个盘子:A直

  • maven手动上传jar包示例及图文步骤过程

    目录 一.maven私服搭建 二.gradle配置 三.打包 四.上传至maven私服中 五.使用 六.刷新gradle 一.maven私服搭建 使用Nexus进行搭建,网上教程很多,不多赘述了. 二.gradle配置 在build.gradle文件的根节点中添加以下内容 //打包源代码 task sourcesJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } artifacts { archives

  • linux环境下java程序打包成简单的hello world输出jar包示例

    本文实例讲述了linux环境下java程序打包成简单的hello world输出jar包.分享给大家供大家参考,具体如下: 1. linux必须已安装java环境,测试 #javac -version javac 1.8.0_20 说明java环境已安装好了 2. 建立目录helloworld,在目录下建立helloworld.java文件 #cd ~ ~# mkdir helloworld ~# cd helloworld ~/helloworld# vi helloworld.java he

  • JDBC-idea导入mysql连接java的jar包(mac)的方法

    前言 1.本文使用的是mysql8.0版本 与5.0版本相比:导包方式相同,后面代码中的注册驱动方式不同 1.mac与pc的idea菜单和图标不是完全相同,但是步骤是差不多的 下载对应版本的jar包 mysql 8.0 jar包下载 点击上面链接,到官网下载jar包 下载后解压即可得到该版本jar包 将jar包在本地放入单独一个文件夹 我将这个jar包放入myJAR文件夹,等下直接将这个文件夹导入idea. 这样做的好处是,以后再使用其它jar包时,直接放到这个文件夹就好,不需要再一个一个导入

  • Java打包工具jar包详解

    Java打包工具是Java开发工具中比较常用的一种,代码重新打包工具jarjar可以帮助你将其它用到的java库打包并嵌入到你自己的项目jar包中.这样做的原因有: 当你发布项目的时候,把用到的库打包进现有项目jar包,可以让发布的这个jar包不比依赖于其它项目的jar包; 当你所用到的java库升级了以后,它所新发布的jar包可能和你现存的项目不匹配,为了保持项目的代码稳定性,你可以把编写代码时所用到的依赖jar包,全部打包进现在的项目jar包,以避免出现这个问题. jarjar可以通过Ant

随机推荐