13 Replies Latest reply on Jan 10, 2008 5:25 AM by Sebastien Degardin

    Design question with Rich GWT Ajax Client

    Sebastien Degardin Newbie

      Hello everyone,

      We have a GWT client which is a very generic engine.
      The Client works almost like a WebService client, it sends JSON formatted message to the server.

      I'm planning to have Session bean method for each JSON request.
      I would also have a mechanism for defining which Method has to handle which message (probably via annotation).

      In such case, how should I hook such request to the seam context ?
      Because if I use a SessionBean directly from the Servlet, it won't be Seam managed ? Right ?

      Tks.

        • 1. Re: Design question with Rich GWT Ajax Client
          Sebastien Degardin Newbie

          of course, I have the ability to add information to each JSON Message.

          • 2. Re: Design question with Rich GWT Ajax Client
            Pete Muir Master

            There are two examples of GWT integration with Seam I know of, both of which take different approaches. The gwt example distributed with Seam in examples/remoting/gwt and the gwt stuff from Rob Jellinghaus http://unrealities.com/seamgwt/article_0.2.html.

            I suspect the remoting/gwt example approach may be more interesting for you...

            • 3. Re: Design question with Rich GWT Ajax Client
              Sebastien Degardin Newbie

               

              "pete.muir@jboss.org" wrote:
              There are two examples of GWT integration with Seam I know of, both of which take different approaches. The gwt example distributed with Seam in examples/remoting/gwt and the gwt stuff from Rob Jellinghaus http://unrealities.com/seamgwt/article_0.2.html.

              I suspect the remoting/gwt example approach may be more interesting for you...


              Excellent, I'm gonna have a look !

              Tks.

              • 4. Re: Design question with Rich GWT Ajax Client
                Sebastien Degardin Newbie

                Those examples are very interesting,

                However, in my case, I'm not using GWT's RCP mechanism but simply JSON over HTTP.

                So, let's say, I have a Controller Servlet handling request and calling different session bean depending on the content of the message.
                there is where I don't know how to integrate Seam in the business.

                Tks.

                • 5. Re: Design question with Rich GWT Ajax Client
                  Pete Muir Master

                  Wrap your calls to Seam components in an ContextHttpServletRequest. Make sure the conversationId is in the request parameter map you pass in.

                  • 6. Re: Design question with Rich GWT Ajax Client
                    Sebastien Degardin Newbie

                     

                    "pete.muir@jboss.org" wrote:
                    Wrap your calls to Seam components in an ContextHttpServletRequest. Make sure the conversationId is in the request parameter map you pass in.


                    Can I put the conversation id into the JSON Message and, in that case, do the same logic as in "SOAPRequestHandler" then without wrapping my code in ContextHttpServletRequest which need the request param ?

                    What SOAPRequestHandler does for each request is :

                    
                     ServletLifecycle.beginRequest(request);
                    
                     ServletContexts.instance().setRequest(request);
                    
                     String conversationId = //I extract my cid here
                     ConversationPropagation.instance().setConversationId( conversationId );
                     Manager.instance().restoreConversation();
                    
                     ServletLifecycle.resumeConversation(request);


                    and after the request completion :

                     String conversationId = Manager.instance().getCurrentConversationId();
                     if (conversationId != null)
                     {
                     //put the cid in my JSON response
                     }
                     Manager.instance().endRequest( new ServletRequestSessionMap(request) );



                    Is that enough to use the Seam-managed persistence context and Seam managed transaction ?

                    Tks

                    • 7. Re: Design question with Rich GWT Ajax Client
                      Sebastien Degardin Newbie

                      Actually, I have the following problem when I try to use ContextHttpServletRequest or write the same code as in SOAPRequestHandler in my Servlet (which parses the JSON mesage and call the Seam component).

                      I'm working with Seam Manager Persistence Context and Seam Managed Transaction.

                      I therefore use @In EntityManager em;

                      here is the code of my SFSB :

                      
                      import java.util.Collection;
                      
                      import javax.ejb.Remove;
                      import javax.ejb.Stateful;
                      import javax.persistence.EntityManager;
                      
                      import org.jboss.seam.annotations.Begin;
                      import org.jboss.seam.annotations.End;
                      import org.jboss.seam.annotations.FlushModeType;
                      import org.jboss.seam.annotations.In;
                      import org.jboss.seam.annotations.Logger;
                      import org.jboss.seam.annotations.Name;
                      import org.jboss.seam.core.Manager;
                      import org.jboss.seam.log.Log;
                      
                      @Stateful
                      @Name("SprintaService")
                      public class SprintaServiceBean implements SprintaService {
                      
                       @Logger
                       private Log log;
                      
                       @In EntityManager em;
                      
                       @Begin(join =true,flushMode = FlushModeType.MANUAL)
                       public void begin () {
                       this.log.info("Begin Conversation id : " + Manager.instance().getCurrentConversationId());
                       }
                      
                       public Person createPerson(Person person) {
                       this.log.info("Continuing Conversation id : " + Manager.instance().getCurrentConversationId());
                       this.em.persist(person);
                       return person;
                       }
                      
                      
                       @End
                       public void end() {
                       this.log.info("Ending Conversation id : " + Manager.instance().getCurrentConversationId());
                       this.em.flush();
                       }
                      
                       @Remove
                       public void remove () {
                      
                       }
                      
                      }
                      


                      If I call the "createPerson" only, it works and commits the transaction.

                      If I call the begin method then the createPerson, I have an Exception, but, after the Servlet complete.

                      Here is the exception :


                      12:27:51,056 INFO [CachedConnectionManager] Closing a connection for you. Please close them yourself: org.jboss.resource.adapter.jdbc.WrappedConnection@a738ee
                      java.lang.Throwable: STACKTRACE
                      at org.jboss.resource.connectionmanager.CachedConnectionManager.registerConnection(CachedConnectionManager.java:290)
                      at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:417)
                      at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:842)
                      at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:88)
                      at org.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:69)
                      at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
                      at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
                      at org.hibernate.jdbc.AbstractBatcher.prepareSelectStatement(AbstractBatcher.java:123)
                      at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:73)
                      at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:99)
                      at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
                      at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
                      at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
                      at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
                      at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
                      at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
                      at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:212)
                      at org.jboss.seam.persistence.EntityManagerProxy.persist(EntityManagerProxy.java:135)
                      at com.mycompany.sprinta.service.SprintaServiceBean.createPerson(SprintaServiceBean.java:50)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:585)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
                      at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
                      at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                      at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:46)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.persistence.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:48)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.persistence.EntityManagerProxyInterceptor.aroundInvoke(EntityManagerProxyInterceptor.java:26)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.persistence.HibernateSessionProxyInterceptor.aroundInvoke(HibernateSessionProxyInterceptor.java:27)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
                      at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:585)
                      at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
                      at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:57)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
                      at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
                      at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
                      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                      at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:204)
                      at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:100)
                      at $Proxy133.createPerson(Unknown Source)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:585)
                      at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
                      at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
                      at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                      at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:41)
                      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                      at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
                      at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
                      at org.javassist.tmp.java.lang.Object_$$_javassist_0.createPerson(Object_$$_javassist_0.java)
                      at com.mycompany.sprinta.server.SprintaServiceServlet.createPerson(SprintaServiceServlet.java:111)
                      at com.mycompany.sprinta.server.SprintaServiceServlet$1.process(SprintaServiceServlet.java:237)
                      at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:53)
                      at com.mycompany.sprinta.server.SprintaServiceServlet.service(SprintaServiceServlet.java:209)
                      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.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)
                      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.web.MultipartFilter.doFilter(MultipartFilter.java:85)
                      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:44)
                      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.security.JaccContextValve.invoke(JaccContextValve.java:84)
                      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
                      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:241)
                      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
                      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                      at java.lang.Thread.run(Thread.java:613)


                      • 8. Re: Design question with Rich GWT Ajax Client
                        Sebastien Degardin Newbie

                        I tried on the same application using the same config and the same EJB's.

                        t works as expected when using JSF.
                        However, when I do the same from my "hand made" Servlet using either ContextualHttpRequest or manualy start Seam context as in the SoapHandler

                        It Does not work and I have the above exception.

                        Any idea ?

                        • 10. Re: Design question with Rich GWT Ajax Client
                          Sebastien Degardin Newbie

                          For info, I've got this on JBoss log when I start the Application :

                          
                          10:04:50,874 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext
                          
                          10:04:51,112 WARN [SessionFactoryImpl] JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()
                          
                          


                          • 11. Re: Design question with Rich GWT Ajax Client
                            Sebastien Degardin Newbie

                            Could anyone simply tell me if i do something wrong or stupid ?


                            Cheers,

                            • 12. Re: Design question with Rich GWT Ajax Client
                              Sebastien Degardin Newbie

                              It seems that SeamPhaseListener does lots of stuff for transaction on the with JSF.

                              When the entitymanager is injected on my SessionBean.
                              If we are on a JSF request the entityManager look like :



                              em = EntityManagerProxy
                              em.delegate = EmtityManagerImpl

                              em.delegate.tx = TransactionImpl
                              em.delegate.tx.tx = JDBCTransaction


                              However, if a receive a request an create a ContextualHttpRequest on my custom servlet, the injected entityManager looks like :


                              em = EntityManagerProxy
                              em.delegate = EmtityManagerImpl

                              em.delegate.tx = TransactionImpl
                              em.delegate.tx.tx = null


                              The underlying transaction is null !
                              Think that info can be usefull.

                              • 13. Re: Design question with Rich GWT Ajax Client
                                Sebastien Degardin Newbie

                                I have a working solution ....

                                in my ContextualHttpRequest, I call the same code as in SeamPhaseListener for JSF.

                                before proceeding the request :


                                void begin()
                                {
                                try
                                {
                                if ( !Transaction.instance().isActiveOrMarkedRollback() )
                                {
                                //log.debug("beginning transaction prior to phase: " + phaseId);
                                Transaction.instance().begin();
                                }
                                }
                                catch (Exception e)
                                {
                                throw new IllegalStateException("Could not start transaction", e);
                                }
                                }



                                at the end :


                                void commitOrRollback()
                                {
                                try
                                {
                                if ( Transaction.instance().isActive() )
                                {
                                //log.debug("committing transaction after phase: " + phaseId);
                                Transaction.instance().commit();
                                }
                                else if ( Transaction.instance().isRolledBackOrMarkedRollback() )
                                {
                                //log.debug("rolling back transaction after phase: " + phaseId);
                                Transaction.instance().rollback();
                                }
                                }
                                catch (Exception e)
                                {
                                throw new IllegalStateException("Could not commit transaction", e);
                                }
                                }



                                I'm sure there are issue with this solution but it works for the begining ...