使用Java读取.jar清单文件

Kyl*_*yle 5 java jar manifest

所以我试图通过检查mainfest文件中的一些值来查看.jar​​是否有效.使用java读取和解析文件的最佳方法是什么?我想过用这个命令来解压缩文件

jar -xvf anyjar.jar META-INF/MANIFEST.MF
Run Code Online (Sandbox Code Playgroud)

但我可以这样做:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF");
Run Code Online (Sandbox Code Playgroud)

然后使用一些缓冲的读者或其他东西来解析文件的行?

谢谢你的帮助...

Rob*_*een 11

使用该jar工具的问题是它需要安装完整的JDK.许多Java用户只会安装JRE,但不包括jar.

此外,jar必须在用户的PATH上.

所以我建议使用适当的API,如下所示:

Manifest m = new JarFile("anyjar.jar").getManifest();
Run Code Online (Sandbox Code Playgroud)

这实际上应该更容易!


Ice*_*erg 5

java.lang.Package 中的 Package 类具有执行您想要的操作的方法。这是使用 Java 代码获取清单内容的简单方法:

String t = this.getClass().getPackage().getImplementationTitle();
String v = this.getClass().getPackage().getImplementationVersion();
Run Code Online (Sandbox Code Playgroud)

我把它放到一个共享实用程序类中的静态方法中。该方法接受一个类句柄对象作为参数。这样,我们系统中的任何类都可以在需要时获取自己的清单信息。显然,可以轻松修改该方法以返回值的数组或哈希图。

调用方法:

    String ver = GeneralUtils.checkImplVersion(this);
Run Code Online (Sandbox Code Playgroud)

名为GeneralUtils.java的文件中的方法:

public static String checkImplVersion(Object classHandle)
{
   String v = classHandle.getClass().getPackage().getImplementationVersion();
   return v;
}
Run Code Online (Sandbox Code Playgroud)

并且要获得清单字段值,而不是您可以通过 Package 类获得的值(例如,您自己的 Build-Date),您需要获取 Main Attibutes 并处理这些值,询问您想要的特定属性。下面的代码是我发现的一个类似问题的轻微修改,可能在这里。(我想归功于它,但我失去了它 - 抱歉。)

将它放在 try-catch 块中,将 classHandle(“this”或 MyClass.class )传递给该方法。“classHandle”是类类型:

  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;
Run Code Online (Sandbox Code Playgroud)