On Oct 15, 2010, at 2:25 AM, Rick McGuire wrote:
> 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.
That makes sense to me. I found that if we eliminated the original error that
prompted OWB to change the classloader provider by fixing the imports for an
OWB bundle, we can avoid the problem entirely.
cf OWB-473. I'm still curious when changing the javassist cl. provider would
be appropriate....
many thanks!
david jencks
>
> 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
>>
>>
>