10 Replies Latest reply on Mar 8, 2007 6:58 AM by holtak

    Seam & clustering

    veterok

      Hello,

      There are some questions about clusterization of Seam contexts and entitiy beans. Let's say I have an entity bean, which is scoped to be in Session Context.

      1) If i configure cluster cache on entity level (EJB3EntityTreeCache + @Cache annotations in entities), will it be working if I access the same entity from other cluster node? As I understand, when referencing seam component by component's name, Seam looks for the component instance in the context first of all. So, does seam replicates instance of the component between contexts in different cluster nodes?

      2) Is there a way to make the whole context to be replicated across all cluster nodes? Let's say I want to replicate session context (assuming that this context contains minimal set of information in order to avoid locks in TreeCache), is it possible?

      3) If it is possible to use both approaches, which of them is more efficient and correct?

      4) Is there any documentation on clustering approaches in Seam?

      Thank you in advance!

        • 1. Re: Seam & clustering
          gavin.king

          I mean to add some clarification to the docs on this.

          The use of CONVERSATION-scoped or SESSION-scoped Entity Bean Seam components is not considered truly cluster-safe.

          If you need to be cluster safe, hold the reference to the entity bean inside a stateful session bean (in any version of Seam) or inside a JavaBean Seam component that implements Mutable (in Seam 1.1).

          This is why we recommend the use of stateful session beans: they are the best way to achieve cluster-safe-ness of conversation-scoped state.

          • 2. Re: Seam & clustering
            veterok

            Gavin, thank you for replying.

            As I understood, seam is not intended to work in clustered environment? Are you planning to do something about it in the future seam versions?

            So, currently we can replicate entities only if they are not bound to any seam context, which, in turn, means that these entities become a non-seam components, which means that we are loosing a lot of features provided by seam. Did I get it right?

            It also would be nice, if you think about providing an ability of replicating seam contexts between different cluster nodes (for some future Seam releases). At least session context should somehow be replicated. For example, currently, I don't have an idea how to implement the Single Sign On feature using Seam in clustered environment.

            I think, that using statefull session beans will not solve all clustering issues. Clustering support should somehow be transparent to Seam users. I mean, it should be configurable on Seam level. Perhaps using additional Seam annotations or xml.. it doesn't matter.

            I'm new to Seam, but it is clear from the first sight, that this framework is quite powerfull and developers get a lot of benefits from using it. Currently, a lot of applications are deployed in clustered environment, so, I guess, it's quite critical to do something with seam about clustering.

            • 3. Re: Seam & clustering
              gavin.king

               

              As I understood, seam is not intended to work in clustered environment?


              Huh???? Of *course* Seam is meant to work in a cluster!

              • 4. Re: Seam & clustering
                gavin.king

                 

                "veterok" wrote:
                So, currently we can replicate entities only if they are not bound to any seam context, which, in turn, means that these entities become a non-seam components, which means that we are loosing a lot of features provided by seam. Did I get it right?


                No, you lose almost nothing by not having your entities be Seam components.

                • 5. Re: Seam & clustering
                  jbmadair

                  Do the cluster issues with Entity beans go away if they are detached from the hibernate session? In that case could I consider them for the most part to be similar in behavior and safety to simple Javabeans?

                  • 6. Re: Seam & clustering
                    gavin.king

                    Nope - not if you put them in the Conversation or Session context, and change their state while they are there. HttpSession does not do dirty checking. You would have to call Context.set() each time you change the object.

                    JavaBean components in Seam 1.1 have special facility for making them cluster-safe - namely the Mutable interface. Entity bean components do not.

                    • 7. Re: Seam & clustering
                      veterok

                       

                      "gavin.king@jboss.com" wrote:
                      As I understood, seam is not intended to work in clustered environment?


                      Huh???? Of *course* Seam is meant to work in a cluster!


                      Which way? All Seam demo applications massively use session and conversation contexts.

                      If some user starts conversation and his next request comes to another cluster node, there is no 'his' conversation context. User's conversation will just break? If so, what should developer do, if there is no possibility to replicate the context?

                      It's also a logical willing to replicate sessions between cluster nodes. How can it be done in terms of Seam?



                      • 8. Re: Seam & clustering
                        holtak

                        Hello Gavin,


                        The use of CONVERSATION-scoped or SESSION-scoped Entity Bean Seam components is not considered truly cluster-safe.

                        If you need to be cluster safe, hold the reference to the entity bean inside a stateful session bean (in any version of Seam) or inside a JavaBean Seam component that implements Mutable (in Seam 1.1).


                        This means, that if I have an Entity Bean "Item" and use it as
                        #{item.price} in JSF, I shoud create an SFSB "ItemClusteraware" with getters for Item item = new Item() or em.find(..) from DB (create/edit-feature), remove @Name from Item and use it like this #{itemClusteraware.item.price} in my JSF?

                        Is that right?

                        I tried to clusterify my application:
                        - put "distributable" into web.xml
                        - anotate Session Beans with @Clustered
                        - I didn`t do do Entity - SFSB stuff mentioned before, because that would mean lot of refactoring.

                        Currently I have only one PC with Jboss with the cluster profile, so I deployed there.

                        The app deployed well and I saw some INFO about TreeCache taking care of SFSB replication.

                        The app works well too, but just for some period of time. After this period, jboss console output gets polluted with this exception once per second to infinity

                        ProjectActionImpl is declard like this
                        @Stateful
                        @Clustered
                        @Name("projectAction")
                        @CacheConfig(idleTimeoutSeconds=SCRatingDefaults.SFSBTimeout)
                        public class ProjectActionImpl implements ProjectAction, Serializable {
                        


                        03:42:07,162 INFO [TxInterceptor] There was a problem handling this request
                        java.lang.RuntimeException: java.lang.RuntimeException: java.io.IOException: org.proaut.scrating.ejb3.session.ProjectActionImpl
                         at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.prePassivate(LifecycleInterceptorHandler.java:169)
                         at org.jboss.ejb3.stateful.StatefulContainer.invokePrePassivate(StatefulContainer.java:382)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.prePassivate(StatefulBeanContext.java:178)
                         at org.jboss.ejb3.cache.tree.StatefulTreeCache$ClusteredStatefulCacheListener.nodePassivate(StatefulTreeCache.java:288)
                         at org.jboss.cache.TreeCache.notifyNodePassivate(TreeCache.java:5739)
                         at org.jboss.cache.interceptors.PassivationInterceptor.invoke(PassivationInterceptor.java:62)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:345)
                         at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:156)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:179)
                         at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5520)
                         at org.jboss.cache.TreeCache.evict(TreeCache.java:3716)
                         at org.jboss.cache.eviction.BaseEvictionPolicy.evict(BaseEvictionPolicy.java:34)
                         at org.jboss.cache.eviction.BaseEvictionAlgorithm.evictCacheNode(BaseEvictionAlgorithm.java:210)
                         at org.jboss.cache.eviction.BaseEvictionAlgorithm.emptyRecycleQueue(BaseEvictionAlgorithm.java:461)
                         at org.jboss.cache.eviction.BaseEvictionAlgorithm.process(BaseEvictionAlgorithm.java:97)
                         at org.jboss.cache.eviction.EvictionTimerTask.run(EvictionTimerTask.java:80)
                         at java.util.TimerThread.mainLoop(Timer.java:512)
                         at java.util.TimerThread.run(Timer.java:462)
                        Caused by: java.lang.RuntimeException: java.io.IOException: org.proaut.scrating.ejb3.session.ProjectActionImpl
                         at org.jboss.ejb3.stateful.StatefulBeanContext.extractBeanAndInterceptors(StatefulBeanContext.java:367)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.getInterceptorInstances(StatefulBeanContext.java:333)
                         at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.getLifecycleInvocationContext(LifecycleInvocationContextImpl.java:65)
                         at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.prePassivate(LifecycleInterceptorHandler.java:160)
                         ... 19 more
                        Caused by: java.io.IOException: org.proaut.scrating.ejb3.session.ProjectActionImpl
                         at org.jboss.serial.classmetamodel.ClassMetamodelFactory.getClassMetaData(ClassMetamodelFactory.java:332)
                         at org.jboss.serial.classmetamodel.StreamingClass.readStream(StreamingClass.java:72)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:381)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
                         at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)
                         at org.jboss.serial.persister.ArrayPersister.readObjectArray(ArrayPersister.java:196)
                         at org.jboss.serial.persister.ArrayPersister.readData(ArrayPersister.java:172)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
                         at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)
                         at org.jboss.serial.io.JBossObjectInputStream.readObjectOverride(JBossObjectInputStream.java:163)
                         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:342)
                         at org.jboss.serial.io.MarshalledObject.get(MarshalledObject.java:68)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.extractBeanAndInterceptors(StatefulBeanContext.java:342)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.getInterceptorInstances(StatefulBeanContext.java:333)
                         at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.getLifecycleInvocationContext(LifecycleInvocationContextImpl.java:65)
                         at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.prePassivate(LifecycleInterceptorHandler.java:160)
                         at org.jboss.ejb3.stateful.StatefulContainer.invokePrePassivate(StatefulContainer.java:382)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.prePassivate(StatefulBeanContext.java:178)
                         at org.jboss.ejb3.cache.tree.StatefulTreeCache$ClusteredStatefulCacheListener.nodePassivate(StatefulTreeCache.java:288)
                         at org.jboss.cache.TreeCache.notifyNodePassivate(TreeCache.java:5739)
                         at org.jboss.cache.interceptors.PassivationInterceptor.invoke(PassivationInterceptor.java:62)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:345)
                         at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:156)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:179)
                        Caused by: java.lang.ClassNotFoundException: org.proaut.scrating.ejb3.session.ProjectActionImpl
                         at java.lang.Class.forName0(Native Method)
                         at java.lang.Class.forName(Class.java:242)
                         at org.jboss.serial.classmetamodel.ClassMetamodelFactory.resolveClassByName(ClassMetamodelFactory.java:269)
                         at org.jboss.serial.classmetamodel.ClassMetamodelFactory.getClassMetaData(ClassMetamodelFactory.java:289)
                         at org.jboss.serial.classmetamodel.StreamingClass.readStream(StreamingClass.java:72)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:381)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
                         at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)
                         at org.jboss.serial.persister.ArrayPersister.readObjectArray(ArrayPersister.java:196)
                         at org.jboss.serial.persister.ArrayPersister.readData(ArrayPersister.java:172)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)
                         at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
                         at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)
                         at org.jboss.serial.io.JBossObjectInputStream.readObjectOverride(JBossObjectInputStream.java:163)
                         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:342)
                         at org.jboss.serial.io.MarshalledObject.get(MarshalledObject.java:68)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.extractBeanAndInterceptors(StatefulBeanContext.java:342)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.getInterceptorInstances(StatefulBeanContext.java:333)
                         at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.getLifecycleInvocationContext(LifecycleInvocationContextImpl.java:65)
                         at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.prePassivate(LifecycleInterceptorHandler.java:160)
                         at org.jboss.ejb3.stateful.StatefulContainer.invokePrePassivate(StatefulContainer.java:382)
                         at org.jboss.ejb3.stateful.StatefulBeanContext.prePassivate(StatefulBeanContext.java:178)
                         at org.jboss.ejb3.cache.tree.StatefulTreeCache$ClusteredStatefulCacheListener.nodePassivate(StatefulTreeCache.java:288)
                         at org.jboss.cache.TreeCache.notifyNodePassivate(TreeCache.java:5739)
                         at org.jboss.cache.interceptors.PassivationInterceptor.invoke(PassivationInterceptor.java:62)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:345)
                         at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:156)
                         at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
                         at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:179)
                         at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5520)
                         at org.jboss.cache.TreeCache.evict(TreeCache.java:3716)
                        


                        the timeout of the SFSB is
                        public static final int SFSBTimeout=((600*60)+60);

                        what exactly is going on? it looks like an EJB3 thing but I didn`t find nothing comparable in the EJB3 forum...

                        thank you,
                        Juraj Holtak

                        • 9. Re: Seam & clustering
                          gavin.king

                           

                          The use of CONVERSATION-scoped or SESSION-scoped Entity Bean Seam components is not considered truly cluster-safe.

                          If you need to be cluster safe, hold the reference to the entity bean inside a stateful session bean (in any version of Seam) or inside a JavaBean Seam component that implements Mutable (in Seam 1.1).


                          This is no longer true in recent versions of Seam. Its safe, but perhaps not efficient.

                          Read the docs, not olde forum posts.

                          • 10. Re: Seam & clustering
                            holtak

                            I got the exception resolved by upgrading Jboss 4.0.5GA to latest EJB3 and JBosssCache 1.4.1SP2.

                            http://www.jboss.com/index.html?module=bb&op=viewtopic&t=96095&view=previous
                            http://jira.jboss.com/jira/browse/EJBTHREE-746


                            Gavin,

                            I`ve read what the reference guide says about clustering, and if I`ve understood it correctly, the cause for the performance degradation is, that seam has to explicitely call .setAttribute as a workaround for servers where replication isn`t triggered by only a property change.

                            If JBoss isn`t on the list of this buggy Servers (I have to find out), why not to have a configuration parameter, where we can explicitely set, if we want to use the workaround or not, defaulting to workaround=yes.

                            Juraj Holtak