2013-10-13 6 views
5

, поэтому я пытаюсь проверить, является ли .jar действительным или нет, путем проверки некоторых значений в файле mainfest. Каков наилучший способ прочитать и проанализировать файл с помощью java? Я думал об использовании этой команды, чтобы извлечь файлИспользование Java для чтения файла манифеста .jar

jar -xvf anyjar.jar META-INF/MANIFEST.MF 

Но я могу просто сделать что-то вроде:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF"); 

Затем использовать некоторые буферизованный читатель или что-то, чтобы разобрать строки файла?

Спасибо за любую помощь ...

+0

Возможный дубликат http://stackoverflow.com/questions/2198525/can-values-defined-in-manifest-mf-be-accessed-programmatically/2198542 –

ответ

8

Проблемы с помощью инструмента jar является то, что она требует полного JDK для установки. У многих пользователей Java будет установлен только JRE, который не включает jar.

Кроме того, jar должен находиться на ПУТЕ пользователя.

Так вместо этого я бы рекомендовал использовать надлежащий API, например:

Manifest m = new JarFile("anyjar.jar").getManifest(); 

Это должно быть на самом деле проще!

+0

О, вау, это имеет смысл. Подождите, так что я также использую Command.exec («код, который извлекает банку»). Есть ли более простой способ сделать это. – Kyle

+0

Да. Но на Stackoverflow уже должен быть вопрос. –

+0

До сих пор я мог найти, используя командную строку, но эта ссылка кажется, что она будет работать, но она выглядит как-то вроде lol. Почему это не так просто, как jarfile.run() или что-то еще. http://www.programcreek.com/2012/08/unzip-a-jar-file-in-java-program/ – Kyle

4

Класс пакета по адресу java.lang.Package имеет способы делать то, что вы хотите. Вот простой способ получить манифест содержимого с помощью кода Java:

String t = this.getClass().getPackage().getImplementationTitle(); 
String v = this.getClass().getPackage().getImplementationVersion(); 

я это в статический метод в общем методе утилита class.The принимает объект класса дескриптора в качестве параметра. Таким образом, любой класс в нашей системе может получить свою собственную информацию о манифесте, когда он в ней нуждается. Очевидно, что метод может быть легко изменен для возврата массива или хэш-карты значений.

вызов метода:

String ver = GeneralUtils.checkImplVersion(this); 

метод в файле GeneralUtils.java:

public static String checkImplVersion(Object classHandle) 
{ 
    String v = classHandle.getClass().getPackage().getImplementationVersion(); 
    return v; 
} 

И получить другие, чем те, которые вы можете получить с помощью манифеста пакета поля-значения класса (например, ваша собственная дата сборки), вы получаете Main Attibutes и работаете с ними, запрашивая тот, который вы хотите. Этот следующий код является небольшим модом из аналогичного вопроса, который я нашел, вероятно, здесь, на SO. (Я хотел бы отдать должное, но я потерял его - извините.)

положил это в блок try-catch, передав в классHandle («this» или MyClass.class) методу. «ClassHandle» имеет тип класса:

String buildDateToReturn = null; 
    try 
    { 
    String path = classHandle.getProtectionDomain().getCodeSource().getLocation().getPath(); 
    JarFile jar = new JarFile(path); // or can give a File handle 
    Manifest mf = jar.getManifest(); 
    final Attributes mattr = mf.getMainAttributes(); 
    LOGGER.trace(" --- getBuildDate: " 
      +"\n\t path:  "+ path 
      +"\n\t jar:  "+ jar.getName() 
      +"\n\t manifest: "+ mf.getClass().getSimpleName() 
      ); 

    for (Object key : mattr.keySet()) 
    { 
     String val = mattr.getValue((Name)key); 
     if (key != null && (key.toString()).contains("Build-Date")) 
     { 
      buildDateToReturn = val; 
     } 
    } 
    } 
    catch (IOException e) 
    { ... } 

    return buildDateToReturn; 
+0

Что касается методов пакета, они должны быть определены в манифесте с использованием правильных имен (например, «Реализация-Версия»), которые находятся в классе java.util.jar.Attributes.Name. Это не особенно хорошо документировано. –

0

Самый простой способ заключается в использовании JarURLConnection класс:

String className = getClass().getSimpleName() + ".class"; 
String classPath = getClass().getResource(className).toString(); 
if (!classPath.startsWith("jar")) { 
    return DEFAULT_PROPERTY_VALUE; 
} 

URL url = new URL(classPath); 
JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); 
Manifest manifest = jarConnection.getManifest(); 
Attributes attributes = manifest.getMainAttributes(); 
return attributes.getValue(PROPERTY_NAME); 

Потому что в некоторых случаях ...class.getProtectionDomain().getCodeSource().getLocation(); дает путь с vfs:/, так что это должно быть обработано дополнительно.

Или с ProtectionDomain:

File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()); 
if (file.isFile()) { 
    JarFile jarFile = new JarFile(file); 
    Manifest manifest = jarFile.getManifest(); 
    Attributes attributes = manifest.getMainAttributes(); 
    return attributes.getValue(PROPERTY_NAME); 
} 
Смежные вопросы