2015-11-05 72 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

这些用于从包中检索属性的方法应该可行,否则它们的目的是什么?我只是解释了它们对jar中的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(); 

尾随斜线似乎很重要。例如。这里是从Apache的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