Hi folks!

A small culprit I found in our proxy code yesterday night:

Consider the following (the 'protected' is important!)

public class User {
  protected String getName() { return "Hans";}
}

User$Proxy extends User
   private User delegate;

  protected String getName {
    return delegate.getName();
  }
}


This code works perfect! But only as long as the User$Proxy and User classes 
are loaded with the same ClassLoader. According to the JVM 2 classes are only 
considered to be in the same package (and thus allows for protected access) if 
they are loaded by the same ClassLoader.
This is what caused problems in Javassist as well, and there we had to do some 
weird hacks with the ClassLoaderProvider factory. 

The solution I did now is the following: I use the ClassLoader of the original 
class to define the Proxy. This works perfectly fine, but only as long as we 
don't proxy classes which are not meant to be 'shared'.  Imagine a full-profile 
EE server where you have e.g. MyFaces in the servers lib folder, which would 
result in a ClassLoader hierarchy similar to:

SystemClassLoader 
 -> EE-server-internal (contains myfaces-*.jar)
    -> EE-server-lib
      -> EAR-A ->warA1, warA2, etc
      -> EAR-B ->warB1, warB2, etc

But any proxies for e.g. javax.faces.context.FacesContext should not be loaded 
with the EE-server-internal ClassLoader but maximum with EAR-A or EAR-B 
ClassLoaders. 


This means we should introduce an upper boundary ClassLoader detection somehow. 
We might need the same for the HierarchicScannerService as well btw.

I already added a detection if proxyClassLoader != proxiedClassClassLoader and 
in that case I skip the proxying of protected methods. We might also 
automatically switch to using reflection in that case, but this is imo not 
required by the specs.

Any objections? Any ideas?


LieGrue,
strub

Reply via email to