How to read meta data from Manifest file

依然范特西╮ 提交于 2019-12-03 22:14:22

问题


I'm trying to extract information from my manifest file to display in one of the methods in my jar file, but seem to be having some issues. Any help is appreciated.

Manifest file:

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
  }
}

Output:

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

So what gives? It looks like the pkg object is being defined correctly, but it doesn't read any of the Specification or Implementation properties.


回答1:


So I finally figured it out and thought I'd share incase anyone else was banging their head against the proverbial brick wall as much as I was. I never could get the methods in the Package class to return anything other than null. See revised code below for how I managed to pull it off.

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);
  }
}

Output:

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

Which is a lot of code to extract four pieces of Metadata.

So if you like a few less lines here's what I used instead:

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);
}



回答2:


Add a slash to the end of your package paths. I.e. change com/example/package1 to com/example/package1/. Ask for some class within the package com.example.package1 (we'll call it Foo) and everything should work fine.

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

The trailing slash seems to matter. E.g. here's the manifest from Apache's 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


来源:https://stackoverflow.com/questions/33553570/how-to-read-meta-data-from-manifest-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!