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