So...
I've spent a day on some thinking and prototyping and hopefully I
got an
idea. Here is an outline:
1. We annotate classes with an object implementing Module interface:
interface Module {
//methods copied from ClassLoading but there is no annotation
argument
Class loadClass(...);
Class loadProxyClass();
}
This makes class loading pluggable - a service can designate it's
own class
loading mechanism.
Note that the methods take boolean verifyCodebaseIntegrity argument. I
think it could be replaced by placing constraints on a Module.
2. Before using a Module we prepare it using a ProxyPreparer - that
way we
make sure we trust the Module before letting it load classes
3. We have a default implementation of Module that delegates class
loading
to ClassLoading:
RmiModule implements Module {
private String annotation;
}
4. There is a single instance of RmiModule called BOOTSTRAP that we
use to
load RmiModule class. This is implemented in:
RmiModule {
...
static Module getModuleOf(final Class cl) {
/*
* RmiModule is equivalent of String annotation
* so it should be available locally
*/
if (cl == RmiModule.class) {
return getBootstrap();
}
final ClassLoader loader = getClassLoader(cl);
if (loader instanceof ModuleClassLoader) {
return ((ModuleClassLoader) loader).getModule();
}
final String annotation =
RMIClassLoader.getClassAnnotation(cl);
return annotation != null ? RmiModule.getInstance(
annotation,getModuleTrust(loader)) : getBootstrap();
}
...
}
5. We use the above method in annotateClass and annotateProxyClass
of our
MarshalOutputStream
6. RmiModule can be verified by ProxyTrustVerifier. It's ProxyTrust
implementation delegates TrustVerifier retrieval to:
public interface ModuleAuthority extends Remote {
TrustVerifier getModuleVerifier() throws RemoteException;
}
7. We implement some helper functions that make it simpler to export a
service and provide its clients with either third party
ModuleAuthority or
designate itself as a ModuleAuthority.
8. Before all this is implemented in PreferredClassProvider we have to
cache association between a ClassLoader and a Module. It's
implemented in
RmiModule.
9. If we implement it in PreferredClassProvider our ClassLoaders can
keep a
reference to associated Module
10. If we implement it in PreferredClassProvider we can have different
ClassLoaders for the same annotation but different ModuleAuthority -
that
would actually allow us to grant permissions to Modules - before
that two
different Modules with the same annotation are going to share
permissions.
I've attached a prototype implementation (note - it is a proto-proto-
prototype) so that you guys can verify if you have some spare time.
Don't know if mailing list server allows attachments.
Michal
On Tuesday 05 of October 2010 16:48:22 Michal Kleczek wrote:
On Tuesday 05 of October 2010 16:36:47 Gregg Wonderly wrote:
On 10/1/2010 12:38 PM, Michal Kleczek wrote:
When I think about it some more - the below idea is not enough
and we
need a more general solution.
How about class annotation not being a String but rather an
object...
I have to give it some more thought.
There are been some thought and discussion about doing this. It is
possible, but the problem becomes that if you send an object with the
annotation, then how does the receiver unmarshall that object? Is
that
object something that everyone knows about ahead of time?
My line of thought was - yes. It would have to be something similar to
ProxyTrust - a factory to receive an Unmarshaller.
I haven't really given it enough thought.
But I am more and more convinced that doing that at the higher (proxy
preparation) level - as I described it earlier - could actually be
enough.
Michal