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

Reply via email to