Как проверить версию файла JAR? - PullRequest
73 голосов
/ 29 апреля 2011

Я сейчас работаю над польским приложением J2ME, просто улучшая его.Я нахожу трудности, чтобы получить точную версию файла JAR.Есть ли способ найти версию файла JAR для импорта в классе?Я имею в виду, если у вас есть что-то, импортируйте xyz;мы можем знать, что версия пакета jar xy принадлежит?

Ответы [ 10 ]

63 голосов
/ 29 апреля 2011

Распакуйте файл JAR и найдите файл манифеста (META-INF\MANIFEST.MF). Файл манифеста файла JAR может содержать номер версии (но не всегда указывается версия).

40 голосов
/ 11 июля 2016

Вам нужно распаковать его и проверить файл META-INF/MANIFEST.MF, например,

unzip -p file.jar | head

или более конкретно:

unzip -p file.jar META-INF/MANIFEST.MF
24 голосов
/ 03 мая 2014

Просто чтобы расширить ответы выше, внутри файла META-INF / MANIFEST.MF в JAR вы, скорее всего, увидите строку: Manifest-Version: 1.0 ← Это НЕ номер версии jar!

Вам нужно поискать Implementation-Version, которая, если она есть, является строкой в ​​виде свободного текста, которая полностью зависит от автора JAR относительно того, что вы там найдете. См. Также Документы Oracle и Спецификация версии пакета

17 голосов
/ 22 декабря 2011

Просто, чтобы завершить ответ выше.

Файл манифеста находится внутри jar по пути META-INF\MANIFEST.MF.

Вы можете просмотреть содержимое jar в любом архиваторе, поддерживающем zip.

11 голосов
/ 04 апреля 2013

Каждая версия баночки имеет уникальную контрольную сумму. Вы можете вычислить контрольную сумму для вашей банки (у которой не было информации о версии) и сравнить ее с различными версиями банки. Мы также можем искать банку, используя контрольную сумму.

См. Этот вопрос для расчета контрольной суммы: Как лучше всего рассчитать контрольную сумму для файла, который находится на моем компьютере?

5 голосов
/ 18 января 2017

Обычно вы должны использовать класс 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 голосов
/ 10 декабря 2015

Эта простая программа перечислит все случаи для версии jar, а именно:

  • Версия, найденная в файле манифеста
  • Не найдена версия в манифесте и даже из имени 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);
    

В нем используется javxt-core jar, который можно загрузить с http://www.javaxt.com/downloads/

2 голосов
/ 19 октября 2017

Я опоздал, но вы можете попробовать следующие два метода

используя эти необходимые классы

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 голос
/ 04 октября 2018

Вы можете отфильтровать версию из файла MANIFEST, используя

unzip -p my.jar META-INF/MANIFEST.MF | grep 'Bundle-Version'

0 голосов
/ 22 мая 2015

Это можно проверить с помощью команды java -jar jarname

...