1 2 Previous Next 16 Replies Latest reply on May 25, 2009 3:46 AM by Nikolay Elenkov

    Seam + Clustered JBoss problem

    Petr Nejedly Newbie

      Hello,


      we're trying to set up JBoss in a cluster (2 nodes, failover) and having problems with the way JBoss / Seam is dealing with destroying SFSBs on a node failure. We have SFSB state replication on, beans are annotated @Clustered and initially we can see them being properly registered in the cache on both nodes.


      On a node failure (CTRL+C) Seam removes the SFSBs and this gets propagated to the other node making the failover scenario unusabe (EJBNotFound exceptions, etc).


      I found this forum, the suggested workaround with separated methods for @Remove and @Destroy doesn't seem to work. Is there any other way to fix this in Seam?


      Regards,


      Petr

        • 1. Re: Seam + Clustered JBoss problem
          Nikolay Elenkov Master

          What version of Seam are you using?
          This has been fixed in 2.1.1. Cf. JBSEAM-3172

          • 2. Re: Seam + Clustered JBoss problem
            Petr Nejedly Newbie

            You are right, Nikolay, my problem was caused by JBSEAM-4029.


            I have another problem, though. It is probably just because of my lack of knowledge how clustering works.


            I managed to set-up SFSB state replication (via JBossCache). The bean (Bean1) has got a Local interface and is annotated @Clustered (for state replication). It also has a variable referencing a Local interface of a SLSB (Bean2).


            After one of the nodes stops the app takes the cached Bean1 but then a method call fails with exception:


            javax.ejb.EJBException: Invalid (i.e. remote) invocation of local interface (null container)
                    at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:80)
                    at $Proxy598.searchTasks(Unknown Source)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                    ....
                    ....
            



            It looks to me Bean1 has got a local reference of Bean2 but on the other node tries to invoke its Remote interface. Is this a proper behaviour? Should I annotate all my EJBs (even stateless) as @Clustered even if I don't want load balancing on EJB level?


            Any help appreciated,


            Petr

            • 3. Re: Seam + Clustered JBoss problem
              Nikolay Elenkov Master

              Petr Nejedly wrote on May 19, 2009 16:07:


              It looks to me Bean1 has got a local reference of Bean2 but on the other node tries to invoke its Remote interface. Is this a proper behaviour? Should I annotate all my EJBs (even stateless) as @Clustered even if I don't want load balancing on EJB level?



              Not 100% sure on this, but you should annotate all session beans with @Clustered (works for me).


              Seam does not handle EJB components that have both a Local and Remote interface too well,
              so you could save yourself some trouble if separate your beans -- the Seam component should
              only have a Local interface, delegate/inherit as appropriate to implement your Remote interface
              (in a another bean).


              HTH

              • 4. Re: Seam + Clustered JBoss problem
                Petr Nejedly Newbie

                The SLSB (Bean2) is actually a Seam component too (stateless scope) and Bean1 gets hold of it via Component.getInstance(bean2). So I guess your suggestion wouldn't work here unless I refactor the lookup (?).


                If I understand it well, the replicated SFSB keeps local Proxy to Bean2 and then cannot invoke it. Is this why we need remote interface?

                • 5. Re: Seam + Clustered JBoss problem
                  Nikolay Elenkov Master

                  What I was saying that Component.getInstance("bean2") might fail if bean2 has both a local and a remote interface.
                  This may not be the source of your error, but to narrow it down lose the remote interface (temporarily),
                  annotate all beans with @Clustered and try it.



                  If I understand it well, the replicated SFSB keeps local Proxy to Bean2 and then cannot invoke it. Is this why we need remote interface?


                  Unless you are caching the reference to bean2(in a field), you should get a fresh instance on every method invocation.
                  If you are caching it, you might get the error above. And, no, you do not need the remote interface for this to work.


                  Any specific reason you are not using injection (@In)?

                  • 6. Re: Seam + Clustered JBoss problem
                    Petr Nejedly Newbie

                    Thanks for your answers, Nikolay.



                    lose the remote interface (temporarily), annotate all beans with @Clustered and try it.

                    That's what I'm doing, I only have local interfaces.



                    Unless you are caching the reference to bean2(in a field), you should get a fresh instance on every method invocation.

                    I'm not caching, but the instance of Bean2 is actually stored in a final variable (so that it can be used in an inner anonymous class). Could this be the problem? Example:


                    private RichfacesDataModelWrapper<TaskInstance> createTaskList(final TaskSearchEvent searchEvent) {  
                            final Bean2 bean2 = BeanFactory.getBean(searchEvent);
                            return new RichfacesDataModelWrapper<TaskInstance>(DEFAULT_SORTING_COLUMN, true, getRowsOfMediumPage()) {
                    
                                public DataPage<TaskInstance> getDataPage(int startRow, int pageSize) throws DataAccessException {
                                    List<TaskInstance> resultList = bean2.searchTasks(searchEvent, getColumn(), isAscending(), startRow, pageSize); 
                                return new DataPage<TaskInstance>(getTotalCount(), startRow, resultList);
                                };                  
                        }




                    Any specific reason you are not using injection (@In)?

                    As you can see, I'm using a factory to get a SLSB based on some criteria.

                    • 7. Re: Seam + Clustered JBoss problem
                      Nikolay Elenkov Master

                      Petr Nejedly wrote on May 21, 2009 11:20:


                      I'm not caching, but the instance of Bean2 is actually stored in a final variable (so that it can be used in an inner anonymous class). Could this be the problem?



                      Unlikely. You could try getting your SLSB reference with a JNDI lookup, to see if that makes a deference.


                      Is the code in searchTasks similar/the same to the createTaskList above?

                      • 8. Re: Seam + Clustered JBoss problem
                        Petr Nejedly Newbie

                        Unlikely. You could try getting your SLSB reference with a JNDI lookup, to see if that makes a deference.

                        Tried that, not sure if it helped. I'm now getting this exception:


                        13:09:44,142 WARN  [LocalProxy] Container jboss.j2ee:ear=vod-ear-2.4.0-SNAPSHOT.ear,jar=portal-ejb-2.4.0-SNAPSHOT.jar,name=PooledTaskSearchManagerBean,service=EJB3,VMID=11d1def534ea1be0:2b3f1698:121630ce2a2:-7ffa is not yet available
                        13:09:44,143 ERROR [viewhandler] Error Rendering View[/pages/workflow/taskList.xhtml]
                        javax.ejb.EJBException: Invalid (i.e. remote) invocation of local interface (null container)
                                at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:80)
                                at $Proxy594.searchTasks(Unknown Source)
                                at uk.co.ondemand.portal.ui.service.Bean1$1.getDataPage(TaskListActionBean.java:413)
                                at uk.co.ondemand.odgcommon.datamodel.DataModelWrapper$LocalDataModel.fetchPage(DataModelWrapper.java:166)
                                at uk.co.ondemand.odgcommon.datamodel.PagedListDataModel.getPage(PagedListDataModel.java:96)
                                at uk.co.ondemand.odgcommon.datamodel.PagedListDataModel.isRowAvailable(PagedListDataModel.java:165)
                                at org.ajax4jsf.model.SequenceDataModel.isRowAvailable(SequenceDataModel.java:171)
                                at org.richfaces.model.ModifiableModel.isRowAvailable(ModifiableModel.java:87)
                                at org.ajax4jsf.component.UIDataAdaptor.isRowAvailable(UIDataAdaptor.java:267)
                                at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:342)
                                at org.ajax4jsf.component.UIDataAdaptor.iterate(UIDataAdaptor.java:1035)
                                at org.ajax4jsf.component.UIDataAdaptor.encodeAjaxChild(UIDataAdaptor.java:498)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:105)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:68)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:116)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:68)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:116)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:68)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:116)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:68)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:116)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:68)
                                at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:116)
                                at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:123)
                                at org.ajax4jsf.component.AjaxViewRoot.encodeAjax(AjaxViewRoot.java:673)
                                at org.ajax4jsf.component.AjaxViewRoot.encodeChildren(AjaxViewRoot.java:544)
                                at javax.faces.component.UIComponent.encodeAll(UIComponent.java:936)
                                at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
                                at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
                                at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:189)
                                at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:109)
                                at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                                at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
                                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                                at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:154)
                                at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:260)
                                at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:366)
                                at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:493)
                                at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                                at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                                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:230)
                                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                                at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
                                at org.jboss.web.tomcat.service.session.ClusteredSessionValve.invoke(ClusteredSessionValve.java:87)
                                at org.jboss.web.tomcat.service.session.JvmRouteValve.invoke(JvmRouteValve.java:84)
                                at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
                                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                                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.jboss.web.tomcat.service.sso.ClusteredSingleSignOn.invoke(ClusteredSingleSignOn.java:676)
                                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
                                at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:437)
                                at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:366)
                                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
                                at java.lang.Thread.run(Thread.java:595)




                        Is the code in searchTasks similar/the same to the createTaskList above?

                        No, searchTasks makes a query into DB and returns actual records that are then being displayed in a DataTable

                        • 9. Re: Seam + Clustered JBoss problem
                          Petr Nejedly Newbie

                          Also, looking at the source of org.jboss.ejb3.stateless.StatelessLocalProxy.invoke() it prints this message when its container attribute is null... In our case it's always the case on the other node, because it's declared as transient and therefore not replicated to the other node.


                          Do I have to mark my member variables (EJBs) as transient and deal with the lookup in @PostActivate ?

                          • 10. Re: Seam + Clustered JBoss problem
                            Nikolay Elenkov Master

                            Petr Nejedly wrote on May 21, 2009 14:28:



                            Tried that, not sure if it helped. I'm now getting this exception:

                            13:09:44,142 WARN  [LocalProxy] Container jboss.j2ee:ear=vod-ear-2.4.0-SNAPSHOT.ear,jar=portal-ejb-2.4.0-SNAPSHOT.jar,name=PooledTaskSearchManagerBean,service=EJB3,VMID=11d1def534ea1be0:2b3f1698:121630ce2a2:-7ffa is not yet available
                            13:09:44,143 ERROR [viewhandler] Error Rendering View[/pages/workflow/taskList.xhtml]
                            javax.ejb.EJBException: Invalid (i.e. remote) invocation of local interface (null container)
                            




                            Well, seem like the same exception to me... If it doesn't work with a JNDI lookup either, this might be a
                            question for the JBoss AS forums (not really a Seam problem). Are you by any chance using the other node
                            to do your JNDI lookups? I.e., are you doing lookup("jndi://node1/fobbar") on node2?



                            No, searchTasks makes a query into DB and returns actual records that are then being displayed in a DataTable


                            I meant is the bean creation/lookup code the same. The BeanFactory part.

                            • 11. Re: Seam + Clustered JBoss problem
                              Nikolay Elenkov Master

                              Petr Nejedly wrote on May 21, 2009 19:01:


                              Do I have to mark my member variables (EJBs) as transient and deal with the lookup in @PostActivate ?


                              So you do have EJB references in your fields. If your are injecting those with @EJB or @In, you
                              do not have to mark them as transient or do anything special. Can you post the full code for Bean2?

                              • 12. Re: Seam + Clustered JBoss problem
                                Petr Nejedly Newbie

                                As far as I know I'm doing just local lookups (no HA-JNDI), using sticky sesions so always using just the one node until it goes down, then the other node picks up the replicated bean and I'm getting this exception.


                                Only Bean2 is created using the BeanFactory (manual lookups), Bean1 is created by Seam when used in jsp via EL.

                                • 13. Re: Seam + Clustered JBoss problem
                                  Petr Nejedly Newbie

                                  Yes, I do. Is that a problem? From what you say I don't have to worry about the injected ones, cool. But as you can see in the code above, I'm doing a manual lookup for Bean2, storing it in a final variable manager so that it's accessible in the anonymous inner class ...

                                  • 14. Re: Seam + Clustered JBoss problem
                                    Nikolay Elenkov Master

                                    Petr Nejedly wrote on May 22, 2009 10:51:


                                    Yes, I do. Is that a problem? From what you say I don't have to worry about the injected ones, cool. But as you can see in the code above, I'm doing a manual lookup for Bean2, storing it in a final variable manager so that it's accessible in the anonymous inner class ...


                                    A local final variable is not a field (instance member variable or whatever you wanna call it). You can use those as much as you want.
                                    If you cache an EJB reference in a field, one node goes down, and you try to access it on the other node, you have a problem.


                                    If you post code, this will be a lot easier...

                                    1 2 Previous Next