/*
 * Copyright 2008-2012 LinkedIn, Inc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package voldemort.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

/**
 * A utility class that abstract out fields from manifest file
 * 
 */
public class ManifestFileReader {

    protected static final Logger logger = Logger.getLogger(ManifestFileReader.class);

    private static String MANIFEST_FILE = "META-INF/MANIFEST.MF";
    private static String RELEASE_VERSION_KEY = "Implementation-Version";

    public static String getReleaseVersion() {
        String version = null;
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(MANIFEST_FILE));
            version = properties.getProperty(RELEASE_VERSION_KEY);
        } catch(IOException e) {
            logger.warn("Unable to load voldemort release version due to the following error:", e);
        }
        return version;
    }
}

/*
 * Copyright 2008-2012 LinkedIn, Inc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package voldemort.utils;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.apache.log4j.Logger;

/**
 * A utility class that abstract out fields from manifest file
 * 
 */
public class ManifestFileReader {

    protected static final Logger logger = Logger.getLogger(ManifestFileReader.class);

    private static String MANIFEST_FILE = "META-INF/MANIFEST.MF";

    // this seems too generic we should have a voldemort-implmentation-version?
    private static String RELEASE_VERSION_KEY = "Implementation-Version";

    public static String getReleaseVersion() {

        try {
            Enumeration<URL> resources = ManifestFileReader.class.getClassLoader()
                                                                 .getResources(MANIFEST_FILE);
            while(resources.hasMoreElements()) {

                Manifest manifest = new Manifest(resources.nextElement().openStream());
                // check that this is your manifest and do what you need or get
                // the next one
                Attributes mainAttribs = manifest.getMainAttributes();
                String version = mainAttribs.getValue(RELEASE_VERSION_KEY);
                if(version != null) {
                    return version;
                }

            }
        } catch(IOException IoE) {
            logger.warn("Unable to load voldemort release version due to the following error:", IoE);
        }

        return null;

    }
}

Use the resources supplied by the classloader to load the manifest file absolute / relative file sytem paths dont work anymore because when you run this in a servlet container everything is relative to its context hence we use the right method of loading resources we probably need a better key to the implmenetation version - because if there exists another manifest file with the same key in the same servlet container we are doomed as we return its implementation version