river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject ClassLoader, ProtectionDomain's Serialization and OSGi
Date Wed, 19 May 2010 13:15:01 GMT
As your well aware, River has some issues with ClassLoaders during 
deserialization.

I've had some thoughts and ideas, about how River might provide a simple 
ClassLoader tree (and the way we package our service interfaces) that 
may solve some of these issues.  Your feedback,  thoughts and ideas 
would be much appreciated.

                    System ClassLoader
                           |
                          \|/
                           |
                  Extension ClassLoader (Includes DynamicPolicyProvider)
                           |
                          \|/
                           |
               Jini Platform ClassLoader
                           |
     ______________________|_______________________
    |                                              |
   \|/                                            \|/
    |                                              |
Application ClassLoader      Smart Proxy ClassLoaders * many



The Jini Platform ClassLoader would contain the Jini Platform and 
Include Service Interface jars and dumb proxy's (reflective) in 
ProtectionDomains with no permission grants.
           
The Application ClassLoader would contain Service implementations, 
including Reggie, Norm, Mahalo, etc, Client Applications and 
ServiceUI's.  The Application ClassLoader itself may have further Child 
ClassLoaders.

Smart Proxy ClassLoaders - There would be one ClassLoader per smart 
proxy (Service), which can contain any number of jar's or external 3rd 
party software library's, all isolated in the Smart Proxy's ClassLoader 
and only visible to Application code through common Service Interfaces 
and classes in the Jini Platform ClassLoader or it's parents.  It's 
implementation doesn't concern the Application.  By allowing Permissions 
to be dynamically granted by CodeSource Certificates, or by CodeSource, 
the proxy can utilise publicly signed, shared jar archives, to provide 
privileged functionality.  Provided the client has authorised it.  This 
may even be prior to Proxy Trust Verification.

All the usual Method Invocation Constraints and Proxy Trust Verification 
still apply, as each CodeSource has a separate ProtectionDomain, a Proxy 
will not be granted any permissions until after Verification, however as 
mentioned above, a Proxy might bundle with it another CodeSource in the 
same ClassLoader under a separate ProtectionDomain that already has some 
permissions granted by way of Signer Certificates.

I've had some thoughts where Codebase services might fit in too, a 
CodeBaseAccessClassLoader implementation could utilise the ServiceID in 
a weak hashtable to locate ClassLoaders during unmarshalling for the 
Smart Proxy's.  The ServiceID would be annotated in addition to Other 
annotated codebase information when the smart proxy communicates 
utilising JERI with its Server. A Smart Proxy ClassLoader would be asked 
first to resolve classes during unarmshalling, it would delegate first 
to its parent, if it fails, the context class loader would be asked to 
resolve the class.

ServiceInterface codebases might consist of  common Interfaces, and 
Parameter / Return Value Classes, Proxy's and Client's utilise to 
communicate (Services Public API), no privileges would be granted to 
this code.

As a use case example, Perhaps a user might browse a list of Service 
Interfaces, before selecting one, followed by lookup of that service, 
upon selecting and unmarshalling a service, the ServiceUI would appear 
for the user to interact with the Service.

IF YOUR INTERESTED IN OSGi READ ON.

What about OSGi?

One of the sticky issues with OSGi is Serialization, developers 
utilising OSGi tackle Serialization by extending ObjectInputStream and 
ObjectOutputStream and annotating a bundle name and version, to locate 
the correct bundle ClassLoader upon deserailization.

As a first step, OSGi can reside where the Application ClassLoader is 
shown in the above tree, as such service implementations and client 
applications that utilise OSGi can utilise Jini Services.  This won't be 
done through the OSGi Service Registrar and it won't stop developers 
from creating OSGi services that utilise Jini Services, but I don't 
think Jini Services should be registered with the OSGi service registrar 
directly, they have different concerns and it is simpler not to do so.

Marshalled Streams could be annotated with a either package names (& 
version) or jar/bundle names and a message digest and the ServiceID 
(where applicable) to assist identifying the correct ClassLoader or 
downloading the correct jar for unmarshalling.  Instead of asking the 
context ClassLoader to resolve classes after failing to resolve a class 
with the Smart Proxy's ClassLoader an OSGi Bundle ClassLoader would be used.

This doesn't mean that at some point in the future River won't itself 
utilise OSGi directly to manage its own modularity.

We can add bundle Manfiests to jsk-platform.jar and other jar's without 
requiring OSGi.

OSGi has a ConditionalPermissionAdmin service and a PermissionAdmin 
service, we might be able to provide an OSGi service that implements 
these by wrapping our DynamicPolicyProvider, we'll see, stay tuned.

The really hard part for full OSGi integration is management of the 
Smart Proxy's ClassLoaders during deserialization, since many services 
can potentially share the same codebase (bundle), however trust concerns 
and permission grants may vary, meaning that identical bundles with 
identical versions would have to reside in different ClassLoaders, this 
differs from OSGi semantics.

The best compromise for now appears to be to place the Smart Proxy 
ClassLoaders outside of OSGi, and allow Jini to isolate them from the 
Application Space, In this way, OSGi applications can utilise non OSGi  
Jini Services.  Instead Jini / River provides the Abstraction / 
Isolation layer.

If we want to modularise River, a good way to begin to would be to make 
some of River's service implementation's Norm, Outrigger, etc OSGi 
bundles.  Bundle activation can then cause these services to be Exported 
and Registered with the Jini Service Registrar.  That would enable life 
cycle management of those services without stopping River etc.

Regards,

Peter.



Mime
View raw message