[jboss-dev-forums] [Design of AOP on JBoss (Aspects/JBoss)] - Classloading problems with ClassProxyFactory
bstansberry@jboss.com
do-not-reply at jboss.com
Fri Apr 25 12:22:08 EDT 2008
I'm seeing intermittent failures in the AS clustering testsuite tests of replicating aspectized web session attributes (aka FIELD granularity session replication.) These are tests where classes are prepared with aopc for use with PojoCache, and then inserted into PojoCache via a web session.
Problem is one of stale (i.e. undeployed) classloaders being used by ClassProxyFactory to create proxies. Specifically:
1) Test class A deploys http-scoped-field.war, classloader BaseClassLoader at 17eb527{vfsfile:/home/bes/dev/jboss/trunk/testsuite/output/lib/http-scoped-field.war} is created.
2) During test, PojoCache uses ClassProxyFactory to create a proxy of java.util.ArrayList. TCCL in effect is the "http-scoped-field.war" classloader, so that is the classloader used to define the proxy class.
3) Test class A finishes, http-scoped-field.war undeploys; all refs to "http-scoped-field.war" classloader should be released.
4) Test class B deploys different war http-field.war".
5) Same as step 2, during test PojoCache uses ClassProxyFactory to create a proxy of java.util.ArrayList. Now TCCL in effect is the "http-field.war" classloader,
Step 5 fails, as ClassProxyFactory finds the cached proxy class from step 2 and tries to create an instance of it:
| 2008-04-24 16:19:42,799 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/http-field].[jsp]] (http-besdev%2F192.168.1.145-8080-2) Servlet.service() for servlet jsp threw exception
| java.lang.IllegalStateException: BaseClassLoader at 17eb527{vfsfile:/home/bes/dev/jboss/trunk/testsuite/output/lib/http-scoped-field.war} classLoader is not connected to a domain (probably undeployed?) for class sun.reflect.ConstructorAccessorImpl
| at org.jboss.classloader.spi.base.BaseClassLoader.loadClassFromDomain(BaseClassLoader.java:723)
| at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:372)
| at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
| at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
| at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
| at sun.misc.Unsafe.defineClass(Native Method)
| at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:45)
| at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:381)
| at java.security.AccessController.doPrivileged(Native Method)
| at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:377)
| at sun.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:76)
| at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:30)
| at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
| at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
| at java.lang.Class.newInstance0(Class.java:350)
| at java.lang.Class.newInstance(Class.java:303)
| at org.jboss.aop.proxy.ClassProxyFactory.newInstance(ClassProxyFactory.java:103)
| at org.jboss.aop.proxy.ClassProxyFactory.newInstance(ClassProxyFactory.java:71)
| at org.jboss.aop.proxy.ClassProxyFactory.newInstance(ClassProxyFactory.java:66)
| at org.jboss.cache.pojo.collection.CollectionInterceptorUtil.createProxy(CollectionInterceptorUtil.java:50)
| at org.jboss.cache.pojo.collection.CollectionInterceptorUtil.createListProxy(CollectionInterceptorUtil.java:97)
| at org.jboss.cache.pojo.impl.CollectionClassHandler.get(CollectionClassHandler.java:63)
| at org.jboss.cache.pojo.impl.PojoCacheDelegate.getObjectInternal(PojoCacheDelegate.java:354)
| at org.jboss.cache.pojo.impl.PojoCacheDelegate.getObject(PojoCacheDelegate.java:102)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.getObject(PojoCacheImpl.java:209)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.org$jboss$cache$pojo$impl$PojoCacheImpl$detach$aop(PojoCacheImpl.java:151)
| at org.jboss.cache.pojo.impl.PojoCacheImpl$PojoCacheImplAdvisor.detach_N_6302035201148273652(PojoCacheImpl$PojoCacheImplAdvisor.java)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.detach(PojoCacheImpl.java)
| at org.jboss.cache.pojo.impl.AdvisedPojoHandler.remove(AdvisedPojoHandler.java:182)
| at org.jboss.cache.pojo.impl.PojoCacheDelegate.removeObject(PojoCacheDelegate.java:276)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.removeObject(PojoCacheImpl.java:171)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.org$jboss$cache$pojo$impl$PojoCacheImpl$detach$aop(PojoCacheImpl.java:154)
| at org.jboss.cache.pojo.impl.PojoCacheImpl$PojoCacheImplAdvisor.detach_N_6302035201148273652(PojoCacheImpl$PojoCacheImplAdvisor.java)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.detach(PojoCacheImpl.java)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.detach(PojoCacheImpl.java:165)
| at org.jboss.cache.pojo.impl.PojoCacheImpl.detach(PojoCacheImpl.java:143)
| at org.jboss.web.tomcat.service.session.FieldBasedJBossCacheService.removePojo(FieldBasedJBossCacheService.java:197)
| at org.jboss.web.tomcat.service.session.FieldBasedClusteredSession.removeJBossInternalAttribute(FieldBasedClusteredSession.java:285)
| at org.jboss.web.tomcat.service.session.JBossCacheClusteredSession.removeAttributeInternal(JBossCacheClusteredSession.java:146)
| at org.jboss.web.tomcat.service.session.ClusteredSession.removeAttributeInternal(ClusteredSession.java:1348)
| at org.jboss.web.tomcat.service.session.ClusteredSession.removeAttributeInternal(ClusteredSession.java:1325)
| at org.apache.catalina.session.StandardSession.removeAttribute(StandardSession.java:1207)
| at org.apache.catalina.session.StandardSession.removeAttribute(StandardSession.java:1179)
| at org.apache.catalina.session.StandardSessionFacade.removeAttribute(StandardSessionFacade.java:140)
| at org.apache.jsp.removeAttribute_jsp._jspService(removeAttribute_jsp.java:60)
| at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
| at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
| at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
| at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
| at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
| at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
| at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
| at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
| at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
| at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
| at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
| at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
| at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
| at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:189)
| at org.jboss.web.tomcat.service.session.ClusteredSessionValve.invoke(ClusteredSessionValve.java:89)
| at org.jboss.web.tomcat.service.session.BatchReplicationClusteredSessionValve.invoke(BatchReplicationClusteredSessionValve.java:102)
| at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
| at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:90)
| at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:96)
| at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
| at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
| at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
| at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
| at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:310)
| at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
| at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
| at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
| at java.lang.Thread.run(Thread.java:595)
|
I've been searching high and low to try and figure out why the old proxy class is being used, since AOP is using a weak ref to cache it. I don't completely understand this (see below) but here's one thing I've seen:
MethodHashesByClass.methodHashesByClass
+ WeakHashMap.table
++ WeakHashMap$Entry.value
+++ HashMap.table
++++ HashMap$Entry.value
+++++ MethodPersistentReference.referencedObject
++++++ SoftReference.referent
+++++++ java.lang.reflect.Method.clazz
++++++++ class Person.classloader
+++++++++ "http-scoped-field.war" classloader classes
++++++++++ proxy to ArrayList
A chain from the proxy class running through a SoftReference. Basically, holding a SoftReference to a Method effectively converts the ClassProxyFactory.proxyCache's weak ref to the proxy class into a SoftReference.
This would help explain the intermittent nature of these failures; if the SoftReference happens to get released, the proxy class is gone and the test passes.
Now, the caveat: while trying to debug this I've developed some tests that load and instantiate AOP-prepared (via aopc) classes in a war, then undeploy the war, fill memory to force all soft references to be cleared, and see then test if the classloader was collected. These are variants on the tests discussed at http://wiki.jboss.org/auth/wiki/ClassloaderLeakUnitTestCase . These tests show the classloader not being released, but an analysis of the heap shows all refs to the classloader going through weak references -- i.e. the classloader should have been collected.
If I run the same test with the same classes, except I haven't run aopc first to prepare the classes, the classloader is released. Been tearing my hair out trying to understand this; using different profiling tools to examing heap, etc. So, there's still some mystery here. :(
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4146873#4146873
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4146873
More information about the jboss-dev-forums
mailing list