Nope, I can't find it... There is some code in skunk/river-modules but
it is really old and not working. I've created a new version but it's
lost...
Anyway the basic idea is to have:
//implementations are requred to implement equals() and hashCode() correctly
//so that instances can be interned
//implementations must be serializable
interface ClassLoaderFactory {
ClassLoader createClassLoader(ClassLoader parent);
//methods required by PreferredClassProvider logic to determine
preferred status
boolean isPreferred(String clazz);
}
final class CodebaseAnnotation implements Serializable {
//from Google Guava
private static final Interner<CodebaseAnnotation> INTERNER =
Interners.newWeakInterner();
//global cache of ClassLoader annotations (weak keys weak values)
//if there is no mapping CodebaseAnnotation with a default
RmiClassLoaderFactory is created
//to handle "local" created ClassLoaders
private static final LoadingCache<ClassLoader, CodebaseAnnotation>
annotationCache =...;
public static CodebaseAnnotation getClassAnnotation(Class clazz) {
//return annotation from annotationCache
}
private final ClassLoaderFactory loaderFactory;
//from Google Guava
//cache of parent-to-child ClassLoader mappings (weak keys weak values)
//if there is no mapping a new ClassLoader is created using loaderFactory
//and the mapping is put into annotationCache - that way ClassLoaders
//created by ClassLoaderFactories do not have to implement anything
relating to annotations
private transient LoadingCache<ClassLoader, ClassLoader> loaderCache;
private synchronized boolean isInstalled() {
return loaderCache != null;
}
private synchronized CodebaseAnnotation install() throws IOException,
SecurityException {
if (!isInstalled()) {
//do loaderFactory verification
//setup loaderCache
}
return this;
}
private Object readResolve() throws IOException {
//make sure there is only one annotation per ClassLoaderFactory
//and it is installed before use
return INTERNER.intern(this).install();
}
//methods from PreferredClassProvider but without the first argument
//logic is basically the same as in PreferredClassProvider
//the only difference is that ClassLoader retrieval is delegated to
loaderCache
public Class loadClass(String name, ClassLoader defaultLoader) {
...
}
public Class loadProxyClass(String[] interfaceNames, ClassLoader
defaultLoader) {
...
}
public ClassLoader getClassLoader() {...}
public boolean equals(Object other) {
if and only if ClassLoaderFactory is equal
}
public int hashCode() {
return loaderFactory.hashCode();
}
}
Changes are also needed in MarshalInputStream and MarshalOutputStream
obviously.
There are also changes needed in some code that depends on codebase
annotations being Strings
The above implementation also has the side-effect of removing lock
contention on global PreferredClassProvider annotation cache.
Regards,
Michal
W dniu 2014-02-25 21:09, Michal Kleczek pisze:
This. I like this. How would this work, would it be an Entry, an
attribute
of the service (perhaps similar to the ServiceUI factory?).
My PoC is attached to one of the issues in Jira (I'll try to find it
tomorrow once I have some more time). It was discussed some time ago
on this list mainly with Peter.
Basically the idea is to change codebase annotation from
java.lang.String which needs to be interpreted by the client to an
object implementing an interface.
This object can be verified in exactly the same way as normal proxies
are verified ( by a TrustVerifier - in particular the
ProxyTrustVerifier ). All that happens during deserialization.
It does not have anything to do with Entries since it is implemented
at the layer below that - hence is available for _all_ downoladed code
(for RemoteEventListeners as well :-) )
Regards,
Michal
--
Michał Kłeczek
XPro Quality Matters
http://www.xpro.biz