Previous Topic

Next Topic

Book Contents

Book Index

JAR utility

As the OSGi Service Platform Service Compendium defines a limited functionality for managing the content of JAR files, in particular of bundle JAR files, the framework exports an utility that provides the most important functionality necessary for viewing and modifying the content of a JAR file.

The JAR utility components are available in the com.prosyst.util.jar package.

Basically, the JAR utility API follows the logic for JAR file I/O operations defined in J2SE by referring to the appropriate methods of the java.util.jar.JarInputStream class. In addition, by using the Certificate Manager service the JAR utility is capable of providing only the trusted certificates a JAR file is signed with.

The JAR utility has two usage aspects – for standard reading and writing of archived content, and for forwarding manifest information to an output stream. The second case is designed for internal use by the framework. The next paragraphs describe the first usage aspect.

Following are some guidelines about the usage of the JAR utility:

This example prints the trusted certificates a bundle with symbolic name test.log.generator is signed with.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.Vector;
import java.util.zip.ZipEntry;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceReference;
import com.prosyst.util.jar.*;
import com.prosyst.mbs.framework.certmanager.CertificateManager;

public class JarUtilTest implements BundleActivator, BundleListener {

  private static final String LOG_GENERATOR_SNAME = "test.log.generator";
  private ServiceReference certDbRef;
  private CertificateManager certDb;

  // Method inherited from BundleListener
  public void bundleChanged(BundleEvent bEvent) {
    Bundle eventSource = bEvent.getBundle();
    // Checking the symbolic name of the installed bundle
    if ((bEvent.getType() == BundleEvent.INSTALLED)
        && (eventSource.getSymbolicName().equals(LOG_GENERATOR_SNAME))) {
      String sourceLocation = eventSource.getLocation();
      // Printing the certificate chains the bundle is signed with
      printCertificate(sourceLocation);
    }
  }

  // Prints the trusted certificate chains of the bundle with the specified location
  private void printCertificate(String sourceLocation) {
    FileInputStream fIn;
    try {
      fIn = new FileInputStream(sourceLocation);
      JarInputStream jarIn = new JarInputStream(fIn, new Manifest(15), certDb);
      Manifest mf = jarIn.getManifest();
      ZipEntry entry = jarIn.getNextEntry();      
      while(entry != null) {
        byte[] buff = new byte[1024];
        try {
          int index = jarIn.read(buff, 0, buff.length);
          while(index != -1) {
            index = jarIn.read(buff, 0, buff.length);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
        JarEntry jarEntry = mf.getJarEntry(entry);
        String[][] certs = jarEntry.getCerts();
        for (int i = 0; (certs != null) && (i < certs.length); i++ ) {
          for (int j = 0; j < certs[i].length; j++ ) {
            System.out.println("[JarUtilTest] " + j + " " + certs[i][j]);
          }  
        }
        entry = jarIn.getNextEntry();  
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  
  // Checks if the test.log.generator bundle is already installed
  private boolean checkIfInstalled(BundleContext bc) {
    Bundle[] bundles = bc.getBundles();
    for (int i = 0; i < bundles.length; i++ ) {
      if (bundles[i].getSymbolicName().equals(LOG_GENERATOR_SNAME)) {
        printCertificate(bundles[i].getLocation());
        return true;
      }
    }
    return false;
  }

  // Methods inherited from BundleActivator
  public void start(BundleContext bc) throws Exception {
    certDbRef = bc.getServiceReference(CertificateManager.class.getName());
    if (certDbRef != null) {
      certDb = (CertificateManager) bc.getService(certDbRef);
      if (!checkIfInstalled(bc)) bc.addBundleListener(this);
    }
  }

  public void stop(BundleContext bc) throws Exception {
    if (certDbRef != null) {
      bc.ungetService(certDbRef);
      certDbRef = null;
      certDb = null;
    }
  }
}