geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rick McGuire <rick...@gmail.com>
Subject Re: Problem in BundleClassLoader with javassist?
Date Fri, 15 Oct 2010 09:25:36 GMT
  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
>
>


Mime
View raw message