The Destiny of a Manifest

A few weeks ago, while working on a personal project, I scraped together a simple utility from a few examples on the web. The problem I’m interested in is reading my application’s MANIFEST.MF ’cause that file is often used to hold interesting information (such as version numbers and authors).

Suppose I want to construct a help page/window, and I want to include information about what version of the application is in use. I could put that information in a properties file somewhere, but there’s often duplicated information in my MANIFEST.MF.

It’s hard to read the MANIFEST.MF in an environment where there are many .jars in the classpath. Reading it in as a resource usually picks the first MANIFEST.MF that the classloader found (often one from the JRE). This code snippet was inspired by a few sources:

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.jar.Manifest;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

public class ManifestReader {

  public static Manifest read(Class<?> mainClass) throws IOException {
    String path = mainClass.getResource(toResourceName(mainClass)).toString();
    String manifestPath = extractRoot(path, mainClass) + "/META-INF/MANIFEST.MF";
    InputStream stream = new URL(manifestPath).openStream();
    try {
      return new Manifest(stream);
    } finally {
      IOUtils.closeQuietly(stream);
    }
  }

  private static String extractRoot(String path, Class<?> mainClass) {
    if (path.contains("!")) {
      return path.substring(0, path.lastIndexOf("!") + 1);
    } else {
      return StringUtils.substringBefore(path, mainClass.getName().replace('.', '/'));
    }
  }

  private static String toResourceName(Class<?> mainClass) {
    return "/" + mainClass.getName().replace('.', '/') + ".class";
  }
}

Once I’ve got the MANIFEST, I can pull name/value pairs out of it to show or manipulate in my application.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply