4 Replies Latest reply on Jun 15, 2012 9:25 AM by rhusar

    SessionScoped Stateful Bean and clustering problem

    tomask7

      Hi, i've created test applicaton for clustering. It's based on "Java EE Web Project" from JBoss developer studio's JBoss Central. My modifications of the project are:

       

      new class in controller package:

      import java.util.concurrent.atomic.AtomicInteger;
      import javax.ejb.Stateful;
      import javax.enterprise.context.SessionScoped;
      import javax.inject.Named;
      import org.jboss.annotation.ejb.Clustered;
      
      @Clustered
      @SessionScoped
      @Stateful
      @Named("bean")
      public class ClusteredSessionBean {
                //private int atribute = 2;
                private AtomicInteger atribute = new AtomicInteger(2); 
      
      
                public void increase() {
         //atribute++;
                          atribute.getAndIncrement();
                }
      
                public int getAtribute() {
                          return atribute.get();
                }
      }
      

       

      web.xml in src/main/webapp/WEB-INF:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
          <!-- Clustering -->
          <distributable/>
      </web-app>
      

       

      dependencies to pom.xml:

            <dependency>
                      <groupId>jboss</groupId>
                      <artifactId>jboss-annotations-ejb3</artifactId>
                      <version>4.2.2.GA</version>
            </dependency>
            <dependency>
                      <groupId>jboss</groupId>
                      <artifactId>jbossha</artifactId>
                      <version>4.2.2.GA</version>
            </dependency>
      

       

      index.xhtml:

      <h:form>
            <h:commandLink action="#{bean.increase}" value="Make it happen" />
      </h:form>
            <h:outputLabel value="#{bean.atribute}" />
      

       

      I started 2 separate instances of jboss 7.1.1 with standalone-ha.xml config... (standalone.bat -c standalone-ha.xml and standalone.bat -c standalone-ha.xml -Djboss.socket.binding.port-offset=100 -Djboss.node.name=daenarys) WAR file is in standalone/deployments/clusterTest.war

       

      problem is, when I open first instance (http://localhost:8080/clusterTest/index.jsf) it is working fine, but second instance ( http://localhost:8180/clusterTest/index.jsf) shows only ERROR 500 ServletException caused by NullPointerException from the bean...

       

      Do you have any idea, how to set this up to work correctly?

       

      Thanks

        • 1. Re: SessionScoped Stateful Bean and clustering problem
          jaikiran

          Tomas, welcome to the forums!

           

          I don't know about the NullPointerException, but you are using an incorrect annotation in your project:

           

          import org.jboss.annotation.ejb.Clustered;

           

          That should be

           

          import org.jboss.ejb3.annotation.Clustered;

           

          It's available in org.jboss.ejb3:jboss-ejb3-ext-api:2.0.0 Maven co-ordinates.

          • 2. Re: SessionScoped Stateful Bean and clustering problem
            wdfink

            In addition to Jaikiran's comment, you should not use any maven dependency to other JBoss versions than  7.1.1.Final (special before AS7) because you will get wrong classes that might not exist in AS7.

            • 3. Re: SessionScoped Stateful Bean and clustering problem
              tomask7

              I've changed dependency and import... but clustering (parallel access) is not working

               

              my new code is:

              import java.util.Map;
              import java.util.Random;
              import java.util.concurrent.ConcurrentHashMap;
              import javax.ejb.Stateful;
              import javax.enterprise.context.SessionScoped;
              import javax.inject.Named;
              import org.jboss.ejb3.annotation.Clustered;
              
              @Clustered
              @SessionScoped
              @Stateful
              @Named("bean")
              public class ClusteredSessionBean {
                        private Map<Long,Integer> map = new ConcurrentHashMap<Long, Integer>();
              
                        public void increase() {
                                  Random r = new Random();
                                  map.put(r.nextLong(), r.nextInt());
                        }
              
                        public int getAtribute() {
                                            return map.size();
                        }
              }
              

               

               

              run the app on first server -> working ok, size of map is increasing (same with previous AtomicInteger)... open second server (in same session = same browser; it's ok with new session), and got crazy exception:

              java.lang.RuntimeException: JBAS010362: Failed to acquire ownership of {[31, 97, 115, -20, -47, 50, 76, 20, -77, 80, 109, -27, 5, 68, 42, -57]}=org.example.cluster.controller.ClusteredSessionBean within 15000 ms
               org.jboss.as.clustering.ejb3.cache.backing.infinispan.InfinispanBackingCacheEntryStore.acquireSessionOwnership(InfinispanBackingCacheEntryStore.java:274)
               org.jboss.as.clustering.ejb3.cache.backing.infinispan.InfinispanBackingCacheEntryStore.get(InfinispanBackingCacheEntryStore.java:173)
               org.jboss.as.ejb3.cache.impl.backing.SerializationGroupMemberContainer.get(SerializationGroupMemberContainer.java:279)
               org.jboss.as.ejb3.cache.impl.backing.SerializationGroupMemberContainer.get(SerializationGroupMemberContainer.java:50)
               org.jboss.as.ejb3.cache.impl.backing.PassivatingBackingCacheImpl.get(PassivatingBackingCacheImpl.java:135)
               org.jboss.as.ejb3.cache.spi.impl.AbstractCache.get(AbstractCache.java:66)
               org.jboss.as.ejb3.cache.spi.impl.AbstractCache.get(AbstractCache.java:39)
               org.jboss.as.weld.ejb.StatefulSessionObjectReferenceImpl.isRemoved(StatefulSessionObjectReferenceImpl.java:151)
               org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:91)
               org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
               org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
               org.example.cluster.controller.ClusteredSessionBean$Proxy$_$$_Weld$Proxy$.toString(ClusteredSessionBean$Proxy$_$$_Weld$Proxy$.java)
               java.lang.String.valueOf(String.java:2826)
               java.lang.StringBuilder.append(StringBuilder.java:115)
               org.jboss.weld.context.SerializableContextualInstanceImpl.toString(SerializableContextualInstanceImpl.java:60)
               java.lang.String.valueOf(String.java:2826)
               java.lang.StringBuilder.append(StringBuilder.java:115)
               org.jboss.weld.context.beanstore.AttributeBeanStore.attach(AttributeBeanStore.java:109)
               org.jboss.weld.context.AbstractBoundContext.activate(AbstractBoundContext.java:66)
               org.jboss.weld.servlet.WeldListener.requestInitialized(WeldListener.java:141)
               org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
               org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
               org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
               org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
               org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
               java.lang.Thread.run(Thread.java:662)
              

               

              Thanks for "fixing" first problem, but I really dont understand this one... I thought, that 2 cluster nodes are supposed to replicate statefull sessionbean content so it can be accessed on both servers (with same session) with same content...

               

              //however, failover is working - when I kill first server, second can be accessed with same content...

              • 4. Re: SessionScoped Stateful Bean and clustering problem
                rhusar

                I thought, that 2 cluster nodes are supposed to replicate statefull sessionbean content so it can be accessed on both servers (with same session) with same content...

                That's not what replication is for. Replication is for high-availability so in case 1 node fails another node picks up but this has nothing to do with supporting concurrent access on multiple nodes. Think about it: if you concurrently accessed the same data (session) on multiple nodes at the same time, which would be the resulting state if you changed it twice? You need another approach for this.

                1 of 1 people found this helpful