[Design of Clustering on JBoss (Clusters/JBoss)] - Re: Scoping of FIELD granularity session pojos
by bstansberry@jboss.com
I'll bring up this general topic when we talk Monday AM.
"bstansberry(a)jboss.com" wrote : Plus I haven't gotten it work properly yet now that PC no longer does it by default. ;)
This was fixed yesterday. Gravitating pojos from the shared region now works, for good or ill, as it did in AS 4.
"bstansberry(a)jboss.com" wrote : My "Con" above refers to the fact that if people try to share pojos or do it accidentally, we can't detect that right away -- the call to attach() with an fqn for the 2nd session will work and create a PojoReference pointing to the _JBossInternal_ region under the first session.
Can PC provide some sort of utility method to tell me where the ref to an object is stored? Or something that tells me if a ref to it is stored in a given region? E.g. I would have code like this:
| Fqn sess2Region = getRegionFqn(sess2);
| if (PojoCacheUtil.isCachedInOtherRegion(pojo, sess2Region)) {
| throw new IllegalStateException("Object " + pojo + " is already stored in another session; sharing objects between sessions is not supported");
| }
|
I could perhaps implement that by looking for a PC interceptor and checking its getFqn() method, but that's a bad idea. :)
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4146877#4146877
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4146877
16 years, 6 months
[Design of AOP on JBoss (Aspects/JBoss)] - Classloading problems with ClassProxyFactory
by bstansberry@jboss.com
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@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@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
16 years, 6 months
[Design of EJB 3.0] - Re: JBMETA-6, JBMETA-25 resolved jndi name
by scott.stark@jboss.org
The jndi policy is only part of the issue. I have hacky logic in the MappedReferenceMetaDataResolverDeployer to set the jndi policy to use if its not set (and its generally not) based on whether its and ejb3/2 deployment and other logic to try to match what the ProxyDeployer is doing.
The ProxyDeployer first looks to @RemoteBinding/@JndiBindingPolicy annotations set in ejb3-interceptors-aop.xml rather than any metadata. Its not clear if these are somehow bridged to the corresponding JBossMetaData.
So the question is how can we get a common view of all jndi names an ejb deployment provides. Right now the MappedReferenceMetaDataResolverDeployer is trying to build this view where it outputs a Map(String, ContainerDependencyMetaData) for all of the ejb endpoints in a deployment. The ContainerDependencyMetaData contains the jndi name(s, currently there is only one) used as the jndi name for reference resolution as well as the supply/demands information for dependencies expressed to the mc.
Getting this explicitly defined at the metadata level seems to be where we need to get to.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4146845#4146845
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4146845
16 years, 6 months