The point of my changes was to make it possible for arbitrary behaviors.  What 
you describe below, could be done as a "version" of the SPI.  The modular 
programming systems like OSGi and Netbeans etc., often have differing needs, 
depending on what you want to expose to "who", and those things might change 
over time, or depending on users. 

Netbeans modules, in particular have a hierarchical structure based on declared 
dependencies.  This can mean that two modules might resolve a class 
differently, depending on what he developer declares.  So, it can be necessary 
to do some interesting things.  The Netbeans system will largely provide the 
right structure for you, so that you can use the "current class" in a 
particular module's class loader as the "parent" for proxy resolution.

Gregg Wonderly

On Aug 19, 2012, at 7:09 AM, Peter Firmstone <[email protected]> wrote:

> 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