[kepler-dev] Kar loading through a class loader

Kevin Ruland kruland at ku.edu
Wed Oct 12 10:58:26 PDT 2005


I went through the fairly simple experiment of taking Chad's
ObjectManager Kar explosion code and rewriting as a class loader.  What
I had done was only a first pass and was fairly functional but did
expose some limitations which might require some thought.

I am a proponent of using mutliple class loaders to support kars.  This
follows the precedence set in both servlet and EJB containers.  There
are numerous examples of how this framework can simplify code deployment
and allow mutiple versions of conflicting packages to coexist.  For
example one can deploy two different webapps which use different
versions of a common jar simultaneously.

Here's the essence of the KSWClassLoader object which I played with
(many details omitted):

public KSWClassLoader extends ClassLoader {

  private KSWFile ksw;

  public KSWClassLoader( File kswFile ) throws IOException {
    super();
    ksw = new KSWFile( kswFile );
  }

  public ActorMetadata[] process() {
    // This is the first entry point.  It is supposed to loop through
the kar file and pull out an array of ActorMetadata
    // to be used by the application.
    // This process should instantiate Class objects using this class
loader.  Then all classes used by these actors
    // would use this class loader for class and resource resolution.
    // It does this with:
    //  For each a in ActorMetadata[] :  this.loadClass( a.getClassName() );
  }

  // Need to override the loadClass method instead of the findClass
method in order to change the default
  // resolution order.  The default resolution order is parent class
loader first, then this class loader.
  public Class loadClass( String clazzname ) throws ClassNotFoundException {
     // Look through the contents of the kar file to find the named
clazzname.
     // if found use defineClass() to load it into the jvm and return it.
     // if not found....
     getParent().loadClass(clazzname);
 }

  public InputStream getResourceAsStream( String name ) {
  // This should be implemented too.
  }

}

This set up worked but was probably because of luck more than anything
because of the duplication of the kar archive classes in the .jars as
well as in the kars..  However, it failed when the actor was not defined
by a .class file but rather by a moml file.  One example of this is
AnyofParameter.kar.  This actor is defined by a moml xml file named
org/resurgence/moml/AnyofParameters.xml.

The problem with moml based actors, is they have no reference to the
custom class loader.  The ActorMetadata contains the xml file name in
the className field and the ActorMetadata constructor tries to pull in
the xml file from the class path.  But the ActorMetadata objects don't
know about the kar file archive and it's custom class loader.

I'm thinking the best solution is to have the ActorMetadata to have a
reference to the custom class loader for the specific kar file.  And
when it needs to load a class (KSWCreator.getActorClass(String, String))
it should instead go to the custom class loader.

One other problem is the LSID resolver,  If one actor in one kar file
attempts to resolve another actor by lsid through the LSID, it probably
should also have a reference to the class loader responsible for the lsid.

Kevin




More information about the Kepler-dev mailing list