reading MANIFEST.MF file from jar file using JAVA

前端 未结 8 1268
情深已故
情深已故 2020-12-02 20:34

Is there any way i can read the contents of a jar file. like i want to read the manifest file in order to find the creator of the jar file and version. Is there any way to a

相关标签:
8条回答
  • 2020-12-02 21:01

    I implemented an AppVersion class according to some ideas from stackoverflow, here I just share the entire class:

    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;
      }
    }
    

    Basically, this class can read version information from the manifest of its own JAR file, or the manifest in it's classes folder. And hopefully it works on different platforms, but I only tested it on Mac OS X so far.

    I hope this would be useful for someone else.

    0 讨论(0)
  • 2020-12-02 21:14
    1. read version;
    2. we copied MANIFEST.MF from jar to user home.
        public void processManifestFile() {
            String version = this.getClass().getPackage().getImplementationVersion();
            LOG.info("Version: {}", version);
            Path targetFile = Paths.get(System.getProperty("user.home"), "my-project", "MANIFEST.MF");
    
            try {
                URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
                JarFile jarFile = new JarFile(url.getFile());
                Manifest manifest = jarFile.getManifest();
                try(FileWriter fw = new FileWriter(targetFile.toFile())) {
                    manifest.getMainAttributes().entrySet().stream().forEach( x -> {
                        try {
                            fw.write(x.getKey() + ": " + x.getValue() + "\n");
                            LOG.info("{}: {}", x.getKey(), x.getValue());
                        } catch (IOException e) {
                            LOG.error("error in write manifest, {}", e.getMessage());
                        }
                    });
                }
                LOG.info("Copy MANIFEST.MF to {}", targetFile);
            } catch (Exception e) {
                LOG.error("Error in processing MANIFEST.MF file", e);
            }
        }
    
    0 讨论(0)
提交回复
热议问题