As you know Gregg's contributed his CodebaseAccessClassLoader alternative to RMIClassLoader.

I figure we need to review MarshalInputStream and MarshalOutputStream, a final interface for CodebaseAccessClassLoader and expected behaviour of Class loading.

I'm also considering class loading for classes other than preferred.

You might have other ideas and opinions, please speak up.

How do we find a suitable parent class loader?

  1. In a modular system, ClassLoaders don't necessarily follow a tree
     hierarchy.
  2. If the class belongs to a smart proxy, the parent ClassLoader is
     the ClassLoader that contains the Service API.
        1. The smart proxy may contain several classes.
        2. Smart proxy classes should generally be preferred.

  3. If we know the name of the service API interface, we can find the
     parent ClassLoader in any system.
        1. Annotate all smart proxy classes with the Service API
           interface name (in addition to the codebase annotation).
        2. Only annotate proxy classes with the proxy Codebase annotation.
        3. During marshaling annotate the stream with the Service API
           interface name and whether the class is preferred (this
           removes the need to download the preferred list from
           codebase URL to confirm if the class is preferred or not.
        4. During unmarshalling, walk the call stack, find the first
           non system ClassLoader and call findClass(String name), keep
           traversing the stack until the Service API class is found.
        5. The ClassLoader of the Service API is the parent
           ClassLoader, this will work as expected in any modular system.
  4. Having found the parent ClassLoader we can now lookup our Map to
     find if a PreferredClassLoader has already been assigned to the
     unmarshaling object class.  This eliminates the need to use the
     problematic Thread context ClassLoader, which may not be set or
     may be set incorrectly.

Lacking codebase annotations, ObjectInputStream usually just tries to resolve classes using the first non null ClassLoader in the call stack (little more to it than that see the spec for details). Standard serialisation doesn't play well with OSGi, in fact exceptions are commonplace during deserialisation with OSGi, there is an easy way to solve this, also annotate the package version, with this information, we can find the correct classloader in a system where more than one ClassLoader may contain different versions of the same classes. In a system where only one version of a package can be found and this package uses a different version, we'll have to accept it, or provide another way for the client to resolve the package, this needs to be a standard interface that can be implemented at the client (or server for objects traveling the other way). Then maven, osgi or some other means can be used to resolve the missing dependency.

Thoughts?

Cheers,

Peter.


Reply via email to