Thursday, January 8, 2015

Java Package: How to Retrieve Its Version Information

Packages define the consistent Java unit that can be developed, packaged, verified, updated, and distributed. Per package manifest information identifies the contents of the package.  When bugs occur, users need to report the following information to aid the debugging process:
  1. What version of the Java Runtime is active?
  2. What version of the Java VM is active?
  3. What are the packages loaded?
  4. What are the package versions?
You can read [1] to answer questions 1 and 2.  In this article, we will tackle issues 3 and 4.

java.lang.Package Object


Package object contain version information—typically, it is stored in the manifest—about the implementation and specification of a Java package. This version information is retrieved and made available by the ClassLoader instance that loaded the class(es). Within each ClassLoader instance, all classes from the same java package have the same Package object.

For demonstration,we have used the following code snippets to retrieve package's version information:


public class GetPackageVersion {

   public static void main(String[] args) {

      // get all the packages
      Package[] pack = Package.getPackages();

      // print all packages, one by one
      for (int i = 0; i < pack.length; i++) {
         System.out.println("" + pack[i].getName());
         System.out.println("  Specification: " + pack[i].getSpecificationVendor() + "," +
                pack[i].getSpecificationTitle() + "," + pack[i].getSpecificationVersion());
         System.out.println("  Implementation: " + pack[i].getImplementationVendor() + "," 
                + pack[i].getImplementationTitle() + "," + pack[i].getImplementationVersion());
      }
   }
}

The Package.getPackages() method gets all the packages currently known for the caller's ClassLoader instance. If the caller's ClassLoader instance is the bootstrap ClassLoader instance,[4] only packages corresponding to classes loaded by the bootstrap ClassLoader instance will be returned.  For example, this is what returned by our bootstrap ClassLoader instance:

sun.reflect
  Specification: Oracle Corporation,Java Platform API Specification,1.8
  Implementation: Oracle Corporation,Java Runtime Environment,1.8.0_40-internal
java.util
  Specification: Oracle Corporation,Java Platform API Specification,1.8
  Implementation: Oracle Corporation,Java Runtime Environment,1.8.0_40-internal
...

MANIFEST.MF


Java products are distributed by putting packages into archive files. Archives include a manifest to identify the product version and packages it contains.  For example, this is the MANIFEST.MF file of rt.jar:

$ cat MANIFEST.MF
...
Implementation-Vendor: Oracle Corporation
Implementation-Title: Java Runtime Environment
Implementation-Version: 1.8.0_40-internal
...
Specification-Vendor: Oracle Corporation
Specification-Title: Java Platform API Specification
Specification-Version: 1.8
...

The output of Package objects from the previous section actually return the version information contained in the manifest file as shown above.

References

  1. Java Products: All About Versions (Xml and More)
  2. Java™ Product Versioning (Java SE 7)
  3. java.lang.Package
  4. WebLogic's Classloading Framework (Xml and More)
  5. Module Versioning Requirements in Jigsaw Project
  6. java.lang.SecurityManager::checkPackageAccess
  7. JAXP: How to Retrieve Its Specification and Implementation Versions (Xml and More)

No comments: