m. vokhm m. vokhm - 5 months ago 19
Java Question

How to obtain a package version from the JAR's manifest, using the getImplementationVersion() method of the Package class

When I prepare my program for deployment, I pack it into a JAR, along with the Eclipse jar-in-jar class loader. When my program runs from the JAR, I need to know a package's version, but I can not obtain it from the jar's manifest a simple and "honest" way.
The manifest looks like this:

Manifest-Version: 1.0
Created-By: 1.8.0_73-b02 (Oracle Corporation)
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Rsrc-Main-Class: com.domain.sp2.controller.Controller
Rsrc-Class-Path: ./ jar-in-jar-loader.zip javahelp-2.0.05.jar json-sim
ple-1.1.1.jar
Class-Path: .

Name: com/domain/sp2/controller/
Implementation-Version: 19


To obtain the package's implementation version, I try to use the simplest and straight-forward way:

package com.domain.sp2.controller;
public class Controller {
...
public static String getBuildNumber() throws IOException {
Package pckg = Controller.class.getPackage();
pr(pckg.getName()); // prints "com.domain.sp2.controller", as expected
return pckg.getImplementationVersion(); // returns null
}
...
}


According to http://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html and http://docs.oracle.com/javase/8/docs/api/java/lang/Package.html#getImplementationVersion-- (and other sources), it should return "19", but it returns null. For the packages of the JRE libraries, it returns correct values. Perhaps I have missed a detail about how to name the package in the manifest, or the reason pertains to the
JarRsrcLoader
- may be it requires some special syntax to address packages. I have also tried
".com/domain/..."
,
"/com/domain/..."
and
".../controller"
, and even
"rsrc:./com/domain..."
as the package name in the manifest - all without success. I could use other ways, e.g. to load the manifest as stream and parse it with the Manifest class, yet I would like to understand what is the correct way to use the
getImplementationVersion()
method.

Answer

You can read the manifest file from the classLoader and get the value you need as below:

URLClassLoader cl = (URLClassLoader) YOUR_CLASS.class.getClassLoader();
try {
  URL url = cl.findResource("META-INF/MANIFEST.MF");
  Manifest manifest = new Manifest(url.openStream());
  Attributes mainAttributes = manifest.getMainAttributes();
  String implVersion = mainAttributes.getValue("Implementation-Version");

  System.out.println(implVersion);
} catch (IOException E) {
      // handle
}
Comments