如何确认jar包的版本

jar包本质上就是一个zip包,可以只用流行的压缩软件进行解压。

jar包的版本被定义在解压后的META-INF\MANIFEST.MF文件中,示例是tomcat8.0.45中catalina.jar包里的MANIFEST.MF文件中的内容:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.7
Created-By: 1.7.0_80-b15 (Oracle Corporation)
Specification-Title: Apache Tomcat
Specification-Version: 8.0
Specification-Vendor: Apache Software Foundation
Implementation-Title: Apache Tomcat
Implementation-Version: 8.0.45
Implementation-Vendor: Apache Software Foundation
X-Compile-Source-JDK: 1.7
X-Compile-Target-JDK: 1.7

在MANIFEST.MF文件中,常见的与版本相关的属性包括Implementation-Version、Specification-Version和Bundle-Version,它们分别表示不同的版本号含义。
1.Implementation-Version:表示当前JAR文件或模块的实现版本号,即程序代码的版本号。如果你的应用程序或库是基于某个框架或API开发的,那么这个版本号通常是由框架或API提供的,用来标识程序代码的版本信息。例如,Spring Framework的JAR文件中的Implementation-Version属性指定了Spring版本号。
2.Specification-Version:表示当前JAR文件或模块实现的规范版本号,即程序代码所遵循的规范的版本号。通常情况下,这个版本号由规范或API的发布者指定,用来标识该规范或API的版本信息。例如,Java SE API的JAR文件中的Specification-Version属性指定了Java SE版本号。
3.Bundle-Version:表示OSGi bundle的版本号,即用于在OSGi容器中进行模块化开发和部署的标准化方式。OSGi是一种面向Java的动态模块化系统,可以将应用程序拆分成多个独立的模块(即bundle),每个bundle可以依赖于其他bundle,并在运行时动态加载和卸载。在OSGi中,每个bundle都必须包含一个MANIFEST.MF文件,其中Bundle-Version属性指定了该bundle的版本号。

需要注意的是,Implementation-Version、Specification-Version和Bundle-Version的格式都是类似的,通常采用“主版本号.次版本号.修订版本号”的形式。例如,1.0.0表示主版本号为1、次版本号为0、修订版本号为0的版本。
在使用JAR文件或模块时,可以通过读取MANIFEST.MF文件中的版本号属性来判断程序代码或规范的版本信息,以确保所使用的版本与预期的版本一致。

如果需要批量获取某个目录下所有jar包的版本,可以参考以下python脚本:

from zipfile import ZipFile
import os
import sys



def showjarversion(start):
    jar_list = []
    #遍历目录
    for relpath, dirs, files in os.walk(start):
        for name in files:
            #判断,如果是jar文件,把文件路径添加到需要检查的路径列表中。
            if name.endswith('.jar'):
                full_path = os.path.join(start, relpath, name)
                jar_list.append(os.path.normpath(os.path.abspath(full_path)))
    for file in jar_list:
        with ZipFile(file) as myzip:
            try:
                myfile = myzip.open('META-INF/MANIFEST.MF')
            #部分jar包打包不规范,没有“META-INF/MANIFEST.MF”,需要进行错误处理。
            except KeyError:
                print(file + '中没有“META-INF/MANIFEST.MF”文件,无法检查版本!')
                continue
            else:
                #将MANIFEST.MF导入字典myfile_dict,方便后面查询。
                myfile_str = myfile.read().decode("utf-8")
                myfile_lines = myfile_str.split("\n")
                myfile_dict = {}
                for line in myfile_lines:
                    if ":" in line:
                        key, value = line.split(":", 1)
                        myfile_dict[key.strip()] = value.strip()
                #取得jar包版本。
                #优先获取Implementation-Version(实现版本)
                #如没有则获取Specification-Version(规范版本)
                #如都没有则获取Bundle-Version(包版本)。
                #如果都没有则报告无法获取版本。
                try:
                    version = myfile_dict['Implementation-Version']
                    print(file + ' 实现版本:' + version)
                except KeyError:
                    try:
                        version = myfile_dict['Specification-Version']
                        print(file + ' 规范版本:' + version)
                    except KeyError:
                        try:
                            version = myfile_dict['Bundle-Version']
                            print(file + ' Bundle版本:' + version)
                        except KeyError:
                            print(file + 'MANIFEST.MF中无版本信息!')

if __name__ == '__main__':
    showjarversion(sys.argv[1])
上一篇
下一篇