如何从清单文件中读取元数据
How to read meta data from Manifest file
我正在尝试从我的清单文件中提取信息以显示在我的 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 对象定义正确,但它没有读取任何规范或实现属性。
所以我终于弄明白了,我想我会分享,以防其他人像我一样用头撞在众所周知的砖墙上。除了 null
之外,我永远无法获得 Package
class 到 return 中的方法。请参阅下面的修订代码,了解我是如何成功实现它的。
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);
}
在包路径的末尾添加斜线。 IE。将 com/example/package1
更改为 com/example/package1/
。在包 com.example.package1
中请求一些 class(我们称之为 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
我的做法
public class UtilReflection {
public static void checkVersion(String[] args){
if(args.length == 1 && "--info".equals(args[0])){
try {
InputStream inputStream = UtilReflection.class.getClassLoader().getResource("META-INF/MANIFEST.MF").openStream();
Manifest manifest = new Manifest(inputStream);
Attributes attrs = manifest.getMainAttributes();
if(attrs == null){
throw new RuntimeException("no attributes found");
}
Set<Object> keys = attrs.keySet();
for(Object key:keys){
System.out.println(String.format("%s: %s", key,attrs.get(key)));
}
} catch (IOException e) {
e.printStackTrace();
}
java.lang.System.exit(0);
}
}
}
public class Main {
public static void main(String[] args) {
UtilReflection.checkVersion(args);
}
}
我正在尝试从我的清单文件中提取信息以显示在我的 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 对象定义正确,但它没有读取任何规范或实现属性。
所以我终于弄明白了,我想我会分享,以防其他人像我一样用头撞在众所周知的砖墙上。除了 null
之外,我永远无法获得 Package
class 到 return 中的方法。请参阅下面的修订代码,了解我是如何成功实现它的。
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);
}
在包路径的末尾添加斜线。 IE。将 com/example/package1
更改为 com/example/package1/
。在包 com.example.package1
中请求一些 class(我们称之为 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
我的做法
public class UtilReflection {
public static void checkVersion(String[] args){
if(args.length == 1 && "--info".equals(args[0])){
try {
InputStream inputStream = UtilReflection.class.getClassLoader().getResource("META-INF/MANIFEST.MF").openStream();
Manifest manifest = new Manifest(inputStream);
Attributes attrs = manifest.getMainAttributes();
if(attrs == null){
throw new RuntimeException("no attributes found");
}
Set<Object> keys = attrs.keySet();
for(Object key:keys){
System.out.println(String.format("%s: %s", key,attrs.get(key)));
}
} catch (IOException e) {
e.printStackTrace();
}
java.lang.System.exit(0);
}
}
}
public class Main {
public static void main(String[] args) {
UtilReflection.checkVersion(args);
}
}