如何查看jar文件的版本?


91

我目前正在开发J2ME波兰语应用程序,只是对其进行了增强。我发现很难获得jar文件的确切版本。有什么方法可以为该类中的导入找到jar文件的版本吗?我的意思是,如果您有东西,请输入xyz;我们可以知道jar xy包所属的版本吗?

Answers:


78

解压缩JAR文件并查找清单文件(META-INF\MANIFEST.MF)。JAR文件的清单文件可能包含版本号(但不一定总是指定版本)。


就像我说的我正在致力于增强应用程序一样,我已经下载了jar文件,并且知道jar文件的版本。但是我想知道该软件包所属的jar的版本,希望您能理解。
Ritesh Mengji

为了进一步说明您,我导入了xyz,我知道xy属于a-4.1.jar,但是我正在使用的应用程序早已开发完毕,我不知道它们使用的是哪个版本的a.jar文件,我我担心该版本,因为某些类已从旧版本的jar中贬值(我认为是),因为即使我的库中有jar,我仍然发现导入无法解决
Ritesh Mengji

就是说,如果您知道他们在构建应用程序时使用的jar版本,那么您还将使用同一版本的jar执行该应用程序吗?
Vivek

1
如果这是您的要求,那么恐怕您将不得不排除已弃用的jar来重建应用程序。因为查找与给定jar相关的版本号就像一对一函数。一个jar文件只有一个版本号。但是,除非开发人员将所需的jar附加到应用程序中,否则在应用程序开发时查找哪个版本的jar听起来非常困难。
Vivek

1
MANIFEST.MF中的记录版本似乎是可选的。sqljdbc42.jar我与Cognos一起使用过的各种文件中都没有记录版本,但是Cognos能够报告版本(4.2.6420.100)。如果清单中未记录该版本,它将从何处获得该版本?
Nick.McDermaid

51

您需要解压缩并检查其META-INF/MANIFEST.MF文件,例如

unzip -p file.jar | head

或更具体:

unzip -p file.jar META-INF/MANIFEST.MF

26

只是为了扩展上面的答案,在JAR的META-INF / MANIFEST.MF文件中,您可能会看到一行:Manifest-Version: 1.0 ←这不是jar版本号!

您需要寻找Implementation-Version哪个(如果存在的话)是自由文本字符串,因此完全取决于JAR的作者以及您在其中可以找到的内容。另请参见Oracle文档程序包版本规范


这个答案(和其他人)目前正在对元讨论
我敢肯定,我错过了一些


11

每个jar版本都有唯一的校验和。您可以为您的jar(没有版本信息)计算校验和,并将其与jar的不同版本进行比较。我们还可以使用校验和搜索一个jar。

请参阅此问题来计算校验和:为我的计算机上的文件计算校验和 的最佳方法是什么?


5
我只是计算了md5罐子并将其粘贴到Google。很好,非常感谢!
mik01aj 2014年

7

基本上,您应该使用使用java.lang.Package类加载器的类来为您提供有关类的信息。

例:

String.class.getPackage().getImplementationVersion();
Package.getPackage(this).getImplementationVersion();
Package.getPackage("java.lang.String").getImplementationVersion();

我认为已知使用该功能的logback可以在其产生的堆栈跟踪中跟踪每个类的JAR名称/版本。

另请参见http://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779


3

这个简单的程序将列出jar版本的所有情况,即

  • 在清单文件中找到的版本
  • 在清单中甚至从罐子名称中都找不到版本
  • 找不到清单文件

    Map<String, String> jarsWithVersionFound   = new LinkedHashMap<String, String>();
    List<String> jarsWithNoManifest     = new LinkedList<String>();
    List<String> jarsWithNoVersionFound = new LinkedList<String>();
    
    //loop through the files in lib folder
    //pick a jar one by one and getVersion()
    //print in console..save to file(?)..maybe later
    
    File[] files = new File("path_to_jar_folder").listFiles();
    
    for(File file : files)
    {
        String fileName = file.getName();
    
    
        try
        {
            String jarVersion = new Jar(file).getVersion();
    
            if(jarVersion == null)
                jarsWithNoVersionFound.add(fileName);
            else
                jarsWithVersionFound.put(fileName, jarVersion);
    
        }
        catch(Exception ex)
        {
            jarsWithNoManifest.add(fileName);
        }
    }
    
    System.out.println("******* JARs with versions found *******");
    for(Entry<String, String> jarName : jarsWithVersionFound.entrySet())
        System.out.println(jarName.getKey() + " : " + jarName.getValue());
    
    System.out.println("\n \n ******* JARs with no versions found *******");
    for(String jarName : jarsWithNoVersionFound)
        System.out.println(jarName);
    
    System.out.println("\n \n ******* JARs with no manifest found *******");
    for(String jarName : jarsWithNoManifest)
        System.out.println(jarName);
    

它使用javaxt-core jar,可以从http://www.javaxt.com/downloads/下载


感谢您对javaxt的引用,我只是从javaxt.com/Tutorials/Jar/…中
David David

1
仅供参考,对于那些谁喜欢Maven来拉javaxt核心,而不是下载JAR,你可以做这些方法之一:gist.github.com/daluu/dda7b29cb5b6e0fbfbaec664eb759739gist.github.com/daluu/52af7eef52563ddf78fe
大卫

2

我迟到了,但是您可以尝试以下两种方法

使用这些所需的类

import java.util.jar.Attributes;
import java.util.jar.Manifest;

这些方法使我可以访问jar属性。我喜欢向后兼容并使用最新的。所以我用这个

public Attributes detectClassBuildInfoAttributes(Class sourceClass) throws MalformedURLException, IOException {
    String className = sourceClass.getSimpleName() + ".class";
    String classPath = sourceClass.getResource(className).toString();
    if (!classPath.startsWith("jar")) {
      // Class not from JAR
      return null;
    }
    String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + 
        "/META-INF/MANIFEST.MF";
    Manifest manifest = new Manifest(new URL(manifestPath).openStream());
    return manifest.getEntries().get("Build-Info");
}

public String retrieveClassInfoAttribute(Class sourceClass, String attributeName) throws MalformedURLException, IOException {
    Attributes version_attr = detectClassBuildInfoAttributes(sourceClass);

    String attribute = version_attr.getValue(attributeName);

    return attribute;
}

当您使用Maven并且需要已知类的pom详细信息时,此方法效果很好。希望这可以帮助。


1

对于Linux,请尝试以下操作:

找 。-name“ YOUR_JAR_FILE.jar” -exec zipgrep“ Implementation-Version:”'{}'\; | awk -F':''{print $ 2}'


1

如果您有winrar,请用winrar打开jar,双击打开folder META-INF。将文件提取MANIFEST.MFCHANGES归档到任何位置(例如桌面)。

在文本编辑器中打开提取的文件:您将看到实现版本或发行版本。



0

我想我会提供一个更新的答案,因为这个问题在搜索中仍然占很高的比例。

检查CLi JAR版本:

在CLi jar文件上运行以下命令:

unzip -p jenkins-cli.jar META-INF/MANIFEST.MF

示例输出:

Manifest-Version: 1.0
Built-By: kohsuke
Jenkins-CLI-Version: 2.210  <--- Jenkins CLI Version
Created-By: Apache Maven 3.6.1
Build-Jdk: 1.8.0_144
Main-Class: hudson.cli.CLI

上面列出了CLi版本。

要获取服务器版本,请运行以下命令:

java -jar ./jenkins-cli.jar -s https://<Server_URL> -auth <email>@<domain>.com:<API Token> version

(以上内容会根据您实施的身份验证而有所不同,请相应更改)

示例输出:

Dec 23, 2019 4:42:55 PM org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar getOrCreateProvider
INFO: getOrCreateProvider(EdDSA) created instance of net.i2p.crypto.eddsa.EdDSASecurityProvider
2.210  <-- Jenkins Server Version

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.