jar中没有主清单属性_还在因 JDK 兼容问题发不同 JAR 包做兼容?MRJAR 了解一下?...

背景

Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在同一个 Jar 包中我们可以包含多个 Java 版本的 class 文件,这样就能做到 Jar 包升级到新的 Java 版本(新特性 API 使用)时不用强迫使用方为了使用新 Jar 包而升级自己的业务模块 Java 版本,也不用针对不同最低支持 Java 版本提供不同的 Jar,真正的做到了一个 Jar 包兼容所有的目的。这样的 Jar 称为 MRJAR。

MRJAR 中的代码包含在不同版本 JDK 下编译的 class 文件。譬如使用 JDK9 编译的类可以调用 JDK9 提供的 API,而使用 JDK8 编译的类可以调用 JDK8 提供的 API,只要保证他们在 MRJAR 中的包名、类名、类对外调用都一致即可。

MRJAR 规则

一般典型情况下的 JAR 包内部包含 class 文件和一个属性META-INF/MANIFEST.MF文件,如下:

- jar-root
  - A.class
  - B.class
  - C.class
- META-INF
  - MANIFEST.MF

MRJAR 扩展自 JAR 的目录结构,扩展了META-INF目录以便存储特定 JDK 版本的 class 文件,META-INF目录包含一个版本子目录,其中可能包含许多子目录,每个目录的命名需要与 JDK 主要版本相同。譬如,对特定于 JDK9 的 class 可以放在META-INF/versions/9目录下,对特定于 JDK10 的 class可以放在META-INF/versions/10目录下等。所以一般典型情况下的 MRJAR 包内部大致如下:

- jar-root
  - A.class
  - B.class
  - C.class
- META-INF
  - MANIFEST.MF
  - versions
    - 9
      - A.class
      - D.class
    - 10
      - A.class
      - B.class

上面的例子中在不同 JDK 环境下运行表现如下:

  • 如果这个 MRJAR 在不支持 MRJAR 的 JDK 环境(譬如 JDK8)下使用,则会被自动兼容当做普通 JAR 使用,即META-INF/versions/目录下都被忽略,直接使用了 root 下的 class,所以无法访问 D。
  • 如果这个 MRJAR 在 JDK9 中使用,则只有 A、B、C、D 这几个 class 可以使用,且这里的 A、D 用的是META-INF/versions/9/下面的 class,其他用的 root 目录下的 class。
  • 对于 JDK10 来说,原理类同上面 JDK9,这里不多解释。只是说当我们在 JDK10 环境使用 C 类时搜索的顺序是先搜索META-INF/versions/10/下是否存在 C,如果不存在则搜索META-INF/versions/9/下是否存在 C,如果不存在则搜索根 root 目录下是否存在,这个查找顺序一定要明白。
  • 对 JDK11 来说,因为不存在META-INF/versions/11/,所以依次在低于自己的版本中搜索,在这里也就等同于在 JDK10 下被命中的类。

制作 MRJAR

JDK9 对生成 JAR 包的各种命令和工具都升级为支持 MRJAR,所以制作 MRJAR 最好直接使用 JDK9 开始的环境,其 jar 命令新增了一个参数为--release,语法如下:

//N代表一个JDK主版本,如JDK9中的9,且N值必须大于等于9;
//所有在--release N之后的文件都会被添加到MRJAR的META-INF/versions/N目录下;

jar  --release N 

假设现在我们准备好了一套 JDK8 的类和一套 JDK12 的类和编译成 class 的产物,如下:

//JDK8的源文件,编译产物目录假设为 jdk8/build/classes/
package cn.yan.mrjar;

public class JarUtil {
    public String func() {
        //JDK8 API实现功能
    }
}

//JDK12的源文件,编译产物目录假设为 jdk12/build/classes/
package cn.yan.mrjar;

public class JarUtil {
    public String func() {
        //JDK12 API实现功能
    }
}

接着我们对上面不同版本生成一个 MRJAR,如下命令:

jar --create --verbose --file test-out.jar
-C jdk8/build/classes .
--release 12 -C jdk12/build/classes .

这样就生成了一个 MRJAR,JDK12 的 JarUtil 类会被放进META-INF/versions/12/目录下,JDK8 的会被放进 root 根目录下。此时的 MRJAR 解压结构如下:

- jar-root
  - cn
    - yan
      - mrjar
        - JarUtil.class
- META-INF
  - MANIFEST.MF
  - versions
    - 9
      - cn
        - yan
          - mrjar
            - JarUtil.class

这样就能将上面制作好的的 MRJAR 在不同 JDK 环境下使用了,你说棒不棒,感觉有用来个在看的同时发给你的好基友呀。

8619d7e3220d9e28e15ece7c51dbbb14.png

0864bffc2e3a539c2ccd30c4d8797585.gif▼往期精彩回顾▼你知道 SimpleDateFormat 的性能问题怎么解决吗?推荐一波代码量、行数、提交量、作者等全维度统计神器

396539001bba2ab3eb00a1e5f375ea37.png点击左下角阅读原文查看历史经典技术问题汇总,看完顺手三连呀~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/498939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java代码例子_程序员快速弄清Java异常体系,拒绝痛苦编程,开发效率加倍

知己知彼方能百战不殆,在小编初学Java时候特别怕程序报异常,经常会因为异常不知所措,相信这个问题应该是所有 初学者都会有的心理感受;如果你也有这种感受,那么只有一种解决方法: 迎难而上,攻克Java异常体系,长痛不如短痛,只要清楚了Java的异常体系,就不会再有这种感受了。下面…

java多条件判断_Java基础教程,第七讲,条件控制、循环语句、数组

学完此次课程,我能做什么?学完此次课程我们将掌握Java中的条件判断和多种循环语句,并且掌握数组的定义和初始化,以及几个常用的数组函数。学习此次课程,需要多久?10分钟课程内容和其他语言一样Java使用条件…

qq机器人源码_基于Springcloud+vue+oAuth2.0全家桶模拟商城项目源码分享

项目介绍功能点:模拟商城,完整的购物流程、后端运营平台对前端业务的支撑,和对项目的运维,有各项的监控指标和运维指标。技术点:核心技术为springcloudvue两个全家桶实现,采取了取自开源用于开源的目标&…

java静态页面我都做不出_Java高并发:静态页面生成方案

提升网站性能的方式有很多,例如有效的使用缓存,生成静态页面等等。今天要说的就是生成静态页面的方式。这个也是我近期一直在搞的一个问题,近期在做使用html servlet做个人网站,为什么是这2个东西呢?1、直接用servlet…

js sleep函数_简单而面试中又常见的知识点:JS执行机制

在开始讲解之前,我们先来看一段代码:console各位小伙伴觉得上面的结果输出会是多少呢?如果你没有了解过javascript的执行机制的话,上面的题目可能会让你崩溃。不过别着急,先往下看,我保证你看到最后&#x…

护卫神怎么增加php版本_护卫神php套件 php版本升级方法(php5.5.24)

最近小编开始学习研究win2008 r2的php环境配置,发现护卫神的php套件非常好用,安装简单,但是因为php版本不是最新的版本,所以就想将php升级下,因为新版的php修复了一些bug所以这里就分享下方法,需要的朋友可…

servlet中doget和dopost的区别_Servlet学习

一.HTTP协议浏览器 ----------------------------------------->服务器请求 http协议&#xff08;包含&#xff1a;1.请求行2.请求头3.空行4.请求实体&#xff09;url浏览器<-------------------------------------------服务器 响应htmlcssjsdata数据特点&#xff1a; 1…

java xml 节点路径,SelectSingleNode使用XPath为已知良好的xml节点路径返回null

回答(9)2 years ago我强烈怀疑问题与名称空间有关 . 尝试摆脱名称空间&#xff0c;你会没事的 - 但显然这对你的实际情况没有帮助&#xff0c;我认为这个文件是固定的 .我不记得如何在XPath表达式中指定命名空间&#xff0c;但我确信这是问题所在 .编辑&#xff1a;好的&#x…

hdfs 多租户_【技术干货】常见的HDFS面试问答精选

最常见的HDFS面试问答1. 什么是HDFS&#xff1f;答&#xff1a;HDFS代表Hadoop分布式文件系统&#xff0c;该系统将大型数据集存储在Hadoop中。它可以在商用硬件上运行&#xff0c;并且具有很高的容错能力。HDFS遵循主/从体系结构&#xff0c;其中许多计算机在集群上运行。群集…

python 根据类名 查找module_关于 Python 命令中的 m 参数

在命令行中使用 Python 时&#xff0c;它可以接收大约 20 个选项(option)&#xff0c;语法格式如下&#xff1a;python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]本文想要聊聊比较特殊的“-m”选项&#xff1a;关于它的典型用法、原理解析与发…

matlab安装程序无法启动jvm_JVM 执行 Java 程序时的内存区域划分

在学习 Java 虚拟机(后面简称&#xff1a; JVM )中的垃圾回收机制(GC)之前&#xff0c;先需要了解 在 JVM 中的 Java 程序(class 文件)加载到内存之后到底是怎么存的。在阅读了 JVM规范 和周志明的 《深入理解Java虚拟机(第2版)》 之后&#xff0c;总结一下JVM中的内存划分以及…

map循环遍历取值_Collection集合框架集和map

Collection集合框架集Java培训之Collection集合框架集MapMap概述Map与Collection并列存在。用于保存具有映射关系的数据:Key-ValueMap 中的 key 和 value 都可以是任何引用类型的数据Map 中的 key 不允许重复key 和 value 之间存在单向一对一关系&#xff0c;即通过指定的 key …

rserve php,使用Rserve远程执行R脚本

Rserve介绍Rserve是一个基于TCP/IP协议的&#xff0c;允许R语言与其他语言通信的C/S结构的程序&#xff0c;支持C/C,Java,PHP,Python,Ruby,Nodejs等。 Rserve提供远程连接&#xff0c;认证&#xff0c;文件传输等功能。我们可以设计R做为后台服务&#xff0c;处理统计建模&…

搜索引擎提交软件_搜索引擎优化的发展史及SEO前景展望

SEO 是随着搜索引擎的普及而出现&#xff0c;并伴随搜索引擎的发展而发展的。关于搜索引擎和搜索引擎优化SEO 最初是怎么诞生的有很多种说法。有一个非常有趣的事实是&#xff0c;最早的一批SEO 甚至可以追溯到Yahoo 出现之前&#xff0c;我们可以把Yahoo 的传世人David Filo 和…

mongodb模糊查询_MongoDB的CRUD基本操作

原创&#xff1a;牛津小马哥Python后端工程师小李哥。在上周的推文中&#xff0c;我们介绍了MongoDB的数据库和集合的操作&#xff0c;现在&#xff0c;让我们来继续学习mongodb的另一个操作&#xff1a;CRUDCRUD操作&#xff1a;创建、读取、更新、删除文档。创建操作&#xf…

设计一个程序实现两个任意长的整数的求和运算_自然数集,整数集,有理数集等都有字母表示,为什么无理数集没有...

在网上翻到一个非常有意思的问题&#xff1a;这个问题乍看起来无厘头&#xff0c;但实际上是个非常深刻的问题&#xff0c;涉及到抽象代数(abstract algebra)的一些基本概念&#xff0c;因此我打算写篇文章来详细阐述一下。人类的数学从数数开始&#xff0c;最早诞生的概念是自…

php strpo函数,php strpos函数有什么用

php strpos函数有什么用&#xff1f;定义和用法strpos() f函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。注释&#xff1a;strpos() 函数是区分大小写的。注释&#xff1a;该函数是二进制安全的。相关函数&#xff1a;strrpos() - 查找字符串在另一字符串中最后一…

oracle 客户端_【数据库 常见术语1】 客户端,服务端

这个系列会介绍并回顾在学习和工作中常碰到的一些名词&#xff0c;以及它们的意思。客户端&#xff0c;服务端&#xff08;以Oracle数据库为例&#xff09;**************************************************************************************【我的理解】 打个比喻&…

多个线程访问统一对象的不同方法_分析| 你未必真的了解线程安全,别骗自己,来看下怎么实现线程安全...

世界那么大&#xff0c;谢谢你来看我&#xff01;&#xff01;关注我你就是个网络、电脑、手机小达人什么是进程&#xff1f;电脑中时会有很多单独运行的程序&#xff0c;每个程序有一个独立的进程&#xff0c;而进程之间是相互独立存在的。比如下图中的QQ、酷狗播放器、电脑管…

php设置mysql查询编码,php连接mysql时怎么设置编码方式

php连接mysql时怎么设置编码方式php连接mysql数据库时&#xff0c;也就是在mysql_connect()语句之后添加“mysql_query("set names utf8");”语句来设置编码方式。注意&#xff1a;是utf8&#xff0c;不是utf-8&#xff1b;网页字符集也最好选用utf-8。在PHP连接数据…