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