使用JAVA从jar文件中读取MANIFEST.MF文件

M.J*_*.J. 29 java jar manifest.mf

有什么办法可以读取jar文件的内容.我希望阅读清单文件,以便找到jar文件和版本的创建者.有没有办法实现同样的目标.

oia*_*kyi 46

下一代码应该有帮助:

JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
Run Code Online (Sandbox Code Playgroud)

异常处理留给你:)

  • 呃...这里的“stream”是什么? (6认同)

fla*_*ash 37

你可以使用这样的东西:

public static String getManifestInfo() {
    Enumeration resEnum;
    try {
        resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
        while (resEnum.hasMoreElements()) {
            try {
                URL url = (URL)resEnum.nextElement();
                InputStream is = url.openStream();
                if (is != null) {
                    Manifest manifest = new Manifest(is);
                    Attributes mainAttribs = manifest.getMainAttributes();
                    String version = mainAttribs.getValue("Implementation-Version");
                    if(version != null) {
                        return version;
                    }
                }
            }
            catch (Exception e) {
                // Silently ignore wrong manifests on classpath?
            }
        }
    } catch (IOException e1) {
        // Silently ignore wrong manifests on classpath?
    }
    return null; 
}
Run Code Online (Sandbox Code Playgroud)

要获取清单属性,您可以迭代变量"mainAttribs",或者如果您知道密钥,则直接检索所需的属性.

此代码循环遍历类路径上的每个jar并读取每个jar的MANIFEST.如果你知道jar的名字,你可能只想查看URL,如果它包含()你感兴趣的jar的名字.


stv*_*per 34

我建议做以下事项:

Package aPackage = MyClassName.class.getPackage();
String implementationVersion = aPackage.getImplementationVersion();
String implementationVendor = aPackage.getImplementationVendor();
Run Code Online (Sandbox Code Playgroud)

其中MyClassName可以是您编写的应用程序中的任何类.

  • 除非您为maven-jar-plugin将addDefaultImplementationEntries添加为true,以使其实际上具有版本信息,否则默认情况下该方法无效。默认情况下,清单文件不包含任何内容。另外@Victor,尝试运行mvn软件包并查看内部是否有正确的信息。通常,这些版本配置位于maven-jar-plugin或maven-war-plugin中,因此未打包的类没有它。 (3认同)
  • 这就是我需要的东西(阅读“实现版本”)。遗憾的是,尽管清单位于“META-INF/MANIFEST.MF”中,但这在未打包的类上对我不起作用。 (2认同)

Jak*_*e W 12

我根据stackoverflow的一些想法实现了一个AppVersion类,这里我只是分享整个类:

import java.io.File;
import java.net.URL;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AppVersion {
  private static final Logger log = LoggerFactory.getLogger(AppVersion.class);

  private static String version;

  public static String get() {
    if (StringUtils.isBlank(version)) {
      Class<?> clazz = AppVersion.class;
      String className = clazz.getSimpleName() + ".class";
      String classPath = clazz.getResource(className).toString();
      if (!classPath.startsWith("jar")) {
        // Class not from JAR
        String relativePath = clazz.getName().replace('.', File.separatorChar) + ".class";
        String classFolder = classPath.substring(0, classPath.length() - relativePath.length() - 1);
        String manifestPath = classFolder + "/META-INF/MANIFEST.MF";
        log.debug("manifestPath={}", manifestPath);
        version = readVersionFrom(manifestPath);
      } else {
        String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";
        log.debug("manifestPath={}", manifestPath);
        version = readVersionFrom(manifestPath);
      }
    }
    return version;
  }

  private static String readVersionFrom(String manifestPath) {
    Manifest manifest = null;
    try {
      manifest = new Manifest(new URL(manifestPath).openStream());
      Attributes attrs = manifest.getMainAttributes();

      String implementationVersion = attrs.getValue("Implementation-Version");
      implementationVersion = StringUtils.replace(implementationVersion, "-SNAPSHOT", "");
      log.debug("Read Implementation-Version: {}", implementationVersion);

      String implementationBuild = attrs.getValue("Implementation-Build");
      log.debug("Read Implementation-Build: {}", implementationBuild);

      String version = implementationVersion;
      if (StringUtils.isNotBlank(implementationBuild)) {
        version = StringUtils.join(new String[] { implementationVersion, implementationBuild }, '.');
      }
      return version;
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }
    return StringUtils.EMPTY;
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上,此类可以从其自己的JAR文件的清单或其classes文件夹中的清单中读取版本信息.希望它可以在不同的平台上运行,但到目前为止我只在Mac OS X上测试过它.

我希望这对其他人有用.