On 10/14/2010 7:29 PM, David Jencks wrote:
I'm seeing a problem I can't figure out with javassist's attempt to create a 
proxy using our BundleClassloader.  Sometimes it works (with classes from 
OpenWebBeans) but sometimes it doesn't (with classes from the bundle the 
BundleClassLoader is wrapping).

Basically, javassist gets a class in the bundle, constructs bytecode for a 
subclass, and calls defineClass on the BundleClassloader: it gets an exception 
back that the superclass (that we started with) can't be loaded.
The problem is not that the superclass can't be "loaded". This is an IllegalAccessError, which is generally a permission problem between the class and its superclass. One cause of this is attempting to define a class using the same package name as the superclass and the two classes are defined using different classloaders (which would be the case here). This would occur if the jar containing the superclass is sealed. Another cause might be the access permissions on the superclass. Any fields or methods of the superclass defined with default scope cannot be accessed by a superclass defined using a different classloader than the superclass. Since this error appears to be occurring on a field access, this is what I suspect is causing the error.

Rick

I mucked around in OWB so that the classloader hidden inside the bundle is 
used, and this problem goes away.  If anyone has some classloader expertise to 
figure out what is going on or make plausible suggestions that would be great.

To see this for yourself, relatively quickly, set the tests to

        <packages>
            <package name="org.jboss.jsr299.tck.tests.lookup.injectionpoint.*"/>
        </packages>

in jcdi-tck-runner/src/test/resources/tck-tests.xml
and run

mvn clean test -Dgeronimo-assembly -Dincontainer -DassemblyId=tomcat7-javaee6

in jcdi-test-runner



I get something like this in the report at 
geronimo/tck/branches/3.0/jcdi-tck-runner/target/surefire-reports/JSR-299 
TCK/JSR-299 TCK.html

java.lang.RuntimeException: by java.lang.IllegalAccessError: class 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean_$$_javassist_14
 cannot access its superclass 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean
        at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:509)
        at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:486)
        at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:422)
        at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:394)
        at 
org.apache.webbeans.util.SecurityUtil$PrivilegedActionForProxyFactory.run(SecurityUtil.java:301)
        at java.security.AccessController.doPrivileged(Native Method)
        at 
org.apache.webbeans.util.SecurityUtil.doPrivilegedCreateClass(SecurityUtil.java:184)
        at 
org.apache.webbeans.proxy.JavassistProxyFactory.getProxyClass(JavassistProxyFactory.java:303)
        at 
org.apache.webbeans.proxy.JavassistProxyFactory.createNormalScopedBeanProxy(JavassistProxyFactory.java:170)
        at 
org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:817)
        at 
org.apache.webbeans.container.InjectableBeanManager.getReference(InjectableBeanManager.java:137)
        at 
org.jboss.jsr299.tck.impl.OldSPIBridge.getInstanceByType(OldSPIBridge.java:42)
        at 
org.jboss.jsr299.tck.AbstractJSR299Test.getInstanceByType(AbstractJSR299Test.java:160)
        at 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.InjectionPointTest.testApiTypeInjectionPoint(InjectionPointTest.java:192)
        at org.jboss.testharness.AbstractTest.run(AbstractTest.java:244)
        at org.jboss.testharness.impl.runner.TestRunner.run(TestRunner.java:61)
        at 
org.jboss.testharness.impl.runner.servlet.ServletTestRunner.doGet(ServletTestRunner.java:120)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
        at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:237)
        at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
        at 
org.apache.geronimo.tomcat.GeronimoStandardContext$SystemMethodValve.invoke(GeronimoStandardContext.java:713)
        at 
org.apache.geronimo.tomcat.valve.GeronimoBeforeAfterValve.invoke(GeronimoBeforeAfterValve.java:47)
        at 
org.apache.geronimo.tomcat.valve.ProtectedTargetValve.invoke(ProtectedTargetValve.java:53)
        at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:146)
        at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
        at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:402)
        at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:254)
        at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
        at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
        at 
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
        at org.apache.geronimo.pool.ThreadPool$1.run(ThreadPool.java:243)
        at 
org.apache.geronimo.pool.ThreadPool$ContextClassLoaderRunnable.run(ThreadPool.java:373)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:637)
Caused by: javassist.CannotCompileException: by java.lang.IllegalAccessError: 
class 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean_$$_javassist_14
 cannot access its superclass 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean
        at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:169)
        at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:501)
        ... 64 more
Caused by: java.lang.IllegalAccessError: class 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean_$$_javassist_14
 cannot access its superclass 
org.jboss.jsr299.tck.tests.lookup.injectionpoint.FieldInjectionPointBean
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at javassist.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:181)
        at javassist.util.proxy.FactoryHelper.toClass(FactoryHelper.java:163)
        ... 65 more
... Removed 29 stack frames
(I've set my geronimo copy to use javassist 3.12.0.GA and OWB 1.1.0-SNAPSHOT so 
the line numbers might be off a little bit).

I can avoid this problem with the following OWB patch which has nothing to 
recommend it except that it works.  It makes javassist use the classloader that 
loaded the provided class (the superclass that can't be found above) instead of 
the BundleClassLoader.

Index: 
webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
===================================================================
--- 
webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
    (revision 1005613)
+++ 
webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
    (working copy)
@@ -282,6 +282,10 @@

     public  Class<?>  getProxyClass(ProxyFactory factory)
     {
+        return doGetProxyClass(factory);
+    }
+
+    private static synchronized Class<?>  doGetProxyClass(ProxyFactory 
factory) {
         Class<?>  proxyClass = null;
         try
         {
@@ -290,6 +294,7 @@
         }
         catch(Exception e)
         {
+            ProxyFactory.ClassLoaderProvider old = 
ProxyFactory.classLoaderProvider;
             ProxyFactory.classLoaderProvider = new 
ProxyFactory.ClassLoaderProvider(){

                 @Override
@@ -300,12 +305,16 @@

             };

-            proxyClass = SecurityUtil.doPrivilegedCreateClass(factory);
+            try {
+                proxyClass = SecurityUtil.doPrivilegedCreateClass(factory);
+            } finally {
+                ProxyFactory.classLoaderProvider = old;
+            }
         }

         return proxyClass;
     }
-
+
     public  ProxyFactory createProxyFactory(Bean<?>  bean) throws Exception
     {
         Set<Type>  types = bean.getTypes();


thanks!
david jencks



Reply via email to