2015-11-05 3 views
2

Я пытаюсь извлечь информацию из моего файла манифеста для отображения в одном из методов в моем jar файле, но, похоже, есть некоторые проблемы. Любая помощь приветствуется.Как читать метаданные из файла манифеста

файл манифеста:

Manifest-Version: 1.0 
Created-By: 1.8.0_60 (Oracle Corporation) 
Main-Class: com.example.package1.myClass 

Name: com/example/package1 
Specification-Title: MyPackage 
Specification-Version: v1.1 
Specification-Vendor: MyCompanyName 
Implementation-Title: MP 
Implementation-Version: 2015-11-05-C 
Implementation-Vendor: MyName 

Name: com/example/package2 
Specification-Title: MySecondaryPackage 
Specification-Version: v2.0 
Specification-Vendor: MyCompanyName 
Implementation-Title: M2ndP 
Implementation-Version: 2015-11-05-C 
Implementation-Vendor: MyName 

myClass.java:

package com.example.package1; 
import com.example.package2; 

class myClass { 
    public static void main(String[] args) { 
    try { 
     myClass clz = new myClass(); 
     Thread.sleep(10000); //pause 10 seconnds so we can see what's spit out 
    } catch (Exception e) { 
    //excluded in example 
    } 
    } 

    public myClass() { 
    Package pkg = getClass().getPackage(); 
    if (pkg == null) 
     System.out.println("No Package Found"); 
    else { 
     System.out.println("specs: " + pkg.getSpecificationTitle() + " - " + pkg.getSpecificationVersion()); 
     System.out.println("imps: " + pkg.getImplementationTitle() + " - " + pkg.getImplementationVersion()); 
     System.out.println("name: " + pkg.getName()); 
    } 
    //other code here excluded from example 
    } 
} 

Выход:

specs: null - null 
imps: null - null 
name: com.example.package1 

Так что это дает? Похоже, что объект pkg определяется правильно, но он не читает никаких свойств спецификации или реализации.

+0

Я думаю, этот вопрос отвечает на ваш вопрос: http://stackoverflow.com/questions/1272648/reading-my-own-jars-manifest –

+0

@Clayton, спасибо, но я Я уже был там и пробовал это. Я попробовал несколько вариантов там, но не получил дальше, чем у меня здесь; имя пакета, но только нулевые значения для свойств. –

+0

Эти методы для извлечения свойств из пакета должны работать, иначе какая цель они служат? Я просто слишком много интерпретирую их функцию против файла manifest.mf в банке? Я чувствую, что мне нужно пропустить что-то простое. Это сводит меня с ума. –

ответ

2

Итак, я, наконец, понял это и подумал, что я поделюсь с тем, что кто-то еще ударил головой о стену пресловутой кирпичной стены так же сильно, как и я. Я никогда не мог получить методы в классе Package, чтобы вернуть что-либо, кроме null. См. Обновленный код ниже, как мне удалось его снять.

package com.example.package1; 
import java.util.*; 
import java.util.jar.*; 
import java.net.*; 

class myClass { 
    public static void main(String[] args) { 
    try { 
    new myClass(); 
    } catch (Exception e) { 
    System.out.println(e.getMessage()); 
    } finally { 
    System.out.println("Done"); 
    try{Thread.sleep(40000);}catch(Exception ee){} 
    } 
    } 

public myClass() throws Exception { 
    String clz = getClass().getSimpleName() + ".class"; 
    String pth = getClass().getResource(clz).toString(); 
    String mnf = pth.substring(0, pth.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF"; 
    String pkg = getClass().getPackage().getName().replaceAll("\\.","/"); 
    URL url = new URL(mnf); 
    Manifest manifest = new Manifest(url.openStream()); 

    Attributes attr = manifest.getAttributes(pkg); 
    String value = attr.getValue("Specification-Title") + " - " + 
    attr.getValue("Implementation-Title") + " " + 
    attr.getValue("Specification-Version") + " build # " + 
    attr.getValue("Implementation-Version"); 
    System.out.println(value); 
    } 
} 

Выход:

MyPackage - MP v1.1 build # 2015-11-05-C 
Done 

Что много кода, чтобы извлечь четыре части метаданных.

Так что, если вам нравится несколько меньше строк, вот что я вместо:

public myClass() throws Exception { 
    Attributes attr = new Manifest(new URL(getClass().getResource(getClass().getSimpleName() + ".class").toString().substring(0, getClass().getResource(getClass().getSimpleName() + ".class").toString().lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF").openStream()).getAttributes(getClass().getPackage().getName().replaceAll("\\.","/")); 
    String value = attr.getValue("Specification-Title") + " - " + attr.getValue("Implementation-Title") + " " + attr.getValue("Specification-Version") + " build # " + attr.getValue("Implementation-Version"); 
    System.out.println(value); 
} 
1

Добавить косую черту в конце ваших путей пакета. То есть изменить com/example/package1 до com/example/package1/. Попросите какой-нибудь класс в пакете com.example.package1 (назовем его Foo), и все должно работать нормально.

Package pkg = com.example.package1.class.getPackage(); 
String specVer = pkg.getSpecificationVersion(); 

Конечная косая черта, по-видимому, имеет значение. Например. вот манифест от ant.jar Апача:

Name: org/apache/tools/ant/ 
Extension-name: org.apache.tools.ant 
Specification-Title: Apache Ant 
Specification-Version: 1.9.6 
Specification-Vendor: Apache Software Foundation 
Implementation-Title: org.apache.tools.ant 
Implementation-Version: 1.9.6 
Implementation-Vendor: Apache Software Foundation 
Смежные вопросы