使用Java读取.jar清单文件
所以我试图通过检查mainfest文件中的一些值来查看.jar是否有效。 使用java读取和解析文件的最佳方法是什么? 我想过用这个命令来解压缩文件
jar -xvf anyjar.jar META-INF/MANIFEST.MF
但我可以这样做:
File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF");
然后使用一些缓冲的读者或其他东西来解析文件的行?
谢谢你的帮助…
使用jar
工具的问题是它需要安装完整的JDK。 许多Java用户只会安装JRE,而不包括jar
。
另外, jar
必须在用户的PATH上。
所以我建议使用适当的API,如下所示:
Manifest m = new JarFile("anyjar.jar").getManifest();
这实际上应该更容易!
java.lang.Package中的Package类具有执行所需操作的方法。 这是使用您的Java代码获取清单内容的简单方法:
String t = this.getClass().getPackage().getImplementationTitle(); String v = this.getClass().getPackage().getImplementationVersion();
我将它放入共享实用程序类中的静态方法。该方法接受类句柄对象作为参数。 这样,我们系统中的任何类都可以在需要时获取自己的清单信息。 显然,可以很容易地修改该方法以返回值的数组或散列映射。
调用方法:
String ver = GeneralUtils.checkImplVersion(this);
名为GeneralUtils.java的文件中的方法:
public static String checkImplVersion(Object classHandle) { String v = classHandle.getClass().getPackage().getImplementationVersion(); return v; }
要获得清单字段值,而不是通过Package类获得的值(例如您自己的构建日期),您将获得主要属性并通过这些值进行处理,询问您想要的特定字段。 以下代码是我发现的类似问题的一个小模块,可能在这里。 (我想赞美它,但我失去了它 – 抱歉。)
把它放在try-catch块中,将classHandle(“this”或MyClass.class)传递给方法。 “classHandle”的类型为Class:
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;
最简单的方法是使用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); }