1 2 3 Previous Next 32 Replies Latest reply on Jan 11, 2013 7:39 AM by gauchors Go to original post
      • 15. Re: Help with back button
        gonorrhea

        thx for your response, I installed FireFly and will take a look.


        But now check this out...


        I exploded the app using h:commandButton and ran a test case (submit and back button).  in the debug.seam page I had cid = 38 after I clicked back button (which is correct/expected b/c as I said before I don't have a @End, only @Begin on submit() method.


        then I exploded the app using a4j:commandButton instead and ran the same test case.  in the debug.seam page I had cid's = 38 and 44 after I click the submit button.  after I click the back button, and refresh debug.seam page, I see only cid = 44.


        So obviously that means Seam is destroying the first LRC when I click back button during 2nd LRC.


        Is this correct or works as intended/designed?  Why?  both are LRC with no @End.  Why is the 1st LRC being destroyed when I am interacting with 2nd LRC tab in IE7?  I have reproduced the original behavior in FF 3 as well, so not too confident it has anything to do with browser being used for test case execution.



        Seam cleans up all contexts on request end (deleting temporary/expired conversations, etc.), so if you have a request (GET in this case), cleanup code should get executed.

        but your statement does not apply to LRC, correct?  I don't see anything at all in my SFSB or pages.xml that is demoting any LRC to temporary conversation.  Why does this happen then?  These are not temporary or expired conversations.  Does this apply to background conversations as well?  That seems strange/erroneous.


        I smell a nasty bug here!


        NOTE: regarding caching, temporary internet files in IE7 are set to every time I visit the webpage, so that means to me no caching AFAIK.

        • 16. Re: Help with back button
          gonorrhea

          My conversation timeout is set to 2 min's in components.xml.


          I just re-tested using 4 tabs (4 LRCs) and reproduced so perhaps the lower cid is timing out and therefore being destroyed.


          So this is a non-issue potentially and not related to my problem.

          • 17. Re: Help with back button
            gonorrhea

            Nikolay Elenkov wrote on May 19, 2009 06:46:


            Your SFSB is destroyed probably because of this:

            2009-05-18 16:19:01,980 DEBUG [org.jboss.seam.core.Manager] Discarding conversation state: 55
            





            That is very obvious.  The question that remains unanswered is why is the LRC for cid=55 being discarded and thereby invoking the destroy() method on my SFSB when there is only one session, one tab and one LRC that must be active/foreground and can't timeout until session times out (AFAIK conversation timeouts apply to background LRCs only).  Is the LRC somehow ending (demoted to temp) when I click back button in browser when using a4j:commandButton?



            Dump conversation/session contents to the log to be sure.

            how do you do that programmatically? I've never done that before in Seam app.


            • 18. Re: Help with back button
              gonorrhea

              And when (i.e. what method) in SFSB would I do the dump to the log?

              • 19. Re: Help with back button
                gonorrhea

                Is nobody experiencing (or experienced) this problem?  Wow, I literally feel like I'm on some scary island...

                • 20. Re: Help with back button
                  gonorrhea

                  deployed code with seam-gen'd Seam 2.1.1.GA project and RF 3.1.1.GA.  reproduced the SFSB destroy() execution on back button click with <a4j:commandButton> in the form.


                  so if this is a bug, it most likely exists in the current codebase.


                  I also noticed that there is only one xhtml file that is using <a4j:commandButton> in the Seam 2.1.1.GA distro (IIRC the excel project).


                  That's kinda sketchy ;(

                  • 21. Re: Help with back button
                    gonorrhea

                    So I'm trying an alternative hack as suggested by a co-worker.


                    Here it is.


                    @Begin(join=true)
                         @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                         public void searchSerialNumber() 
                         {     
                              serialNumberSearchComplete = false;
                              try{
                                   Thread.sleep(10000);
                              }
                              catch (Exception e){
                                   log.error("thread.sleep exception occurred: ", e);
                              }
                              equipmentDetailBean = new EquipmentDetailBean();
                              equipmentDetailBean.setDescription("desc");
                              equipmentDetailBean.setEarliestReturnDate(new Date());
                              equipmentDetailBean.setMacAddress("MC90098II8");
                              
                              showCreateNew = true;
                              serialNumberSearchComplete = true;
                         }
                         
                         public void synchronizeJsFunction(){
                              while(!serialNumberSearchComplete){
                                   try{
                                        Thread.sleep(500);
                                   }
                                   catch (Exception e){
                                        log.error("thread.sleep exception occurred: ", e);
                                   }
                              }
                         }



                    The Thread.sleep(10000) is to simulate the time it takes to exec a stored proc and get a resultList.


                    xhtml:


                    <h:form id="jsFunctionForm">
                                   <a4j:jsFunction name="rerenderModal" 
                                             reRender="dataModalDiv"
                                             action="#{testManageEquipment.synchronizeJsFunction}"
                                             oncomplete="Richfaces.showModalPanel('mpanel1');" />
                    </h:form> 
                    
                    <h:form>
                                                     
                                                               <b>Serial Number:</b> 
                                                               
                                                              <h:inputText id="serialNumberId" 
                                                                          value="#{testManageEquipment.serialNumber}">
                                                               </h:inputText>
                                                               
                                                               <!-- <a4j:commandButton id="searchButton"                                             
                                                                                   value="Search" 
                                                                                   type="button"                                                               
                                                                                   action="#{testManageEquipment.searchSerialNumber}"
                                                                                   reRender="form1"> 
                                                               </a4j:commandButton> -->           
                                                                <h:commandButton id="searchButton"                                             
                                                                                   value="Search"
                                                                                   onclick="rerenderModal();" 
                                                                                   action="#{testManageEquipment.searchSerialNumber}"   
                                                                                   reRender="form1">
                                                               </h:commandButton>                             
                                                     <BR/>
                                                     <BR/>
                                                       <BR/>
                                                  </h:form>



                    Notice the onclick event handler for h:commandButton.  The goal here is to display the plz wait modal for the entire duration of the req/resp cycle (i.e. as long as it takes to call and execute and return from the searchSerialNumber SFSB method).


                    I'm wondering how Seam handles multi-threaded access, if at all?


                    I'm seeing the following in the console:


                    16:13:24,765 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_58] - Abort of action id a2e050c:78e:4a133b2f:cf invoked while multiple threads active within it.
                    16:13:24,765 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.CheckedAction_2] - CheckedAction::check - atomic action a2e050c:78e:4a133b2f:cf aborting with 1 threads active!
                    

                    • 22. Re: Help with back button
                      gonorrhea

                      It seems to consistently work as expected (i.e. display modal the entire duration on click of commandButton) the first time you click the h:commandButton, but for subsequent submissions in the same LRC, the modal does not display nearly long enough or seemingly at all.

                      • 23. Re: Help with back button
                        gonorrhea

                        So I changed the scope of the SFSB from conversation to session and voila:


                        Caused by: java.lang.IllegalStateException: could not acquire lock on @Synchronized component: testManageEquipment
                             at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:41)
                             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
                             at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
                             at org.javassist.tmp.java.lang.Object_$$_javassist_6.searchSerialNumber(Object_$$_javassist_6.java)
                             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.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:329)
                             at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:342)
                             at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
                             at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
                             at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
                             at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
                             at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
                             ... 52 more



                        So I added @Synchronized at the class level which in effect makes all business methods single-threaded (i.e. same as conversation-scoped bean now).


                        So what.

                        • 24. Re: Help with back button
                          kapitanpetko

                          Arbi Sookazian wrote on May 19, 2009 18:33:



                          Nikolay Elenkov wrote on May 19, 2009 06:46:


                          Your SFSB is destroyed probably because of this:

                          2009-05-18 16:19:01,980 DEBUG [org.jboss.seam.core.Manager] Discarding conversation state: 55
                          





                          That is very obvious.  The question that remains unanswered is why is the LRC for cid=55 being discarded and thereby invoking the destroy() method on my SFSB when there is only one session, one tab and one LRC that must be active/foreground and can't timeout until session times out (AFAIK conversation timeouts apply to background LRCs only).  Is the LRC somehow ending (demoted to temp) when I click back button in browser when using a4j:commandButton?



                          Indeed it is obvious :) Should've made this clear, but I was implying that you conversation is a temporary one.
                          Are you sure it is a LRC? Even if you have only one tab, if it has AJAX components inside, stuff could go wrong:
                          say, conversation ID being lost on AJAX post back.




                          Dump conversation/session contents to the log to be sure.

                          how do you do that programmatically? I've never done that before in Seam app.



                          You could observe org.jboss.seam.begin/endConversation to see when a conversation starts/ends.
                          Inside your observer try something like this:


                          Conversation c = Conversation.instance();
                          log.debug(String.format("id: %s; isLongRunning %s; viewId: %s", c
                                               .getId(), c.isLongRunning(), c.getViewId()));
                          



                          You could also install your own HttpSessionAttributeListener to be notified
                          whenever anything changes in your session, but you would have to do some
                          filtering to get meaningful result.


                          • 25. Re: Help with back button
                            gonorrhea

                            Tomorrow at work I will try the @Observer.


                            I was using the debug.seam page which lists all the LRCs and I'm sure from that page that the temporary conversation is being promoted to LRC when I click the a4j:commandButton (or h:commandButton) to submit the form and call the searchSerialNumber() method in SFSB which is annotated with @Begin.


                            So as I understand, once the @Begin method completes successfully, the conversation is now promoted to LRC.  And then I refresh the debug.seam page and lo and behold there's now an LRC there!


                            I guess it's possible that cid is getting lost on AJAX postback (IIRC I don't see a cid=x in the URL until I navigate to 2nd page - but that may be normal, as IIRC that happens the same way with h:commandButton).  I will need to determine that.  It's behaving as if the LRC is being demoted to temp conversation and that's why the destroy() method is being called.


                            So in the org.jboss.seam.core.Manager component:


                             /**
                                * Make a long-running conversation temporary.
                                */
                               public void endConversation(boolean beforeRedirect)
                               {
                                  if ( isLongRunningConversation() )
                                  {
                                     log.debug("Ending long-running conversation");
                                     if ( Events.exists() ) Events.instance().raiseEvent("org.jboss.seam.endConversation");
                                     setLongRunningConversation(false);
                                     destroyBeforeRedirect = beforeRedirect;
                                     endNestedConversations( getCurrentConversationId() );
                                     storeConversationToViewRootIfNecessary();
                                  }
                               }



                            The endConversation event is raised here.  Ok cool.


                            So I will try the observer (not familiar with HttpSessionAttributeListener) to observe this raised event.  Thx for your responses.


                            • 26. Re: Help with back button
                              gonorrhea

                              Ok so I tried the @Observer and the org.jboss.seam.endConversation event is apparently not being raised (org.jboss.seam.beginConversation is being raised).


                              I enter a value in HtmlInputText and click the a4j:commandButton to submit form (triggers postback).  This is what I then see in console:


                              08:48:41,943 INFO  [TestManageEquipmentAction] begin beginConversation()
                              08:48:41,943 INFO  [TestManageEquipmentAction] id: 2; isLongRunning true; viewId: null



                              I click the a4j:commandLink in separate h:form to proceed to next page, this is what I then see in console:


                              08:50:12,318 INFO  [TestBackButtonAction] begin goNext()
                              08:50:12,318 INFO  [TestBackButtonAction] id: 2; isLongRunning true; viewId: /TestManageEquipment.xhtml



                              I click browser back button, this is what i then see in console:


                              08:51:18,442 INFO  [ProfilingInterceptor] *** Entering method: getSerialNumber
                              08:51:18,442 INFO  [ProfilingInterceptor] *** Entering method: getEquipmentDetailBean
                              08:51:18,599 INFO  [ProfilingInterceptor] *** Entering method: destroy
                              08:51:18,599 INFO  [TestManageEquipmentAction] in destroy()



                              I noticed that after I hit back button in the browser, the cid is missing in the URL for the first page:


                              http://localhost:8080/BETS/TestManageEquipment.seam



                              I am not starting from a login page like in booking example.  We are using NTLM silent authentication as part of our template/framework.  Not sure if that's relevant to problem or not.


                              Here is a comparison of URLs and appended cid's with the public booking app (I back/forward buttoned all the way thru the entire LRC) :


                              http://demo.flamingo.exadel.com/booking/home.seam
                              
                              http://demo.flamingo.exadel.com/booking/main.seam?cid=50822
                              
                              http://demo.flamingo.exadel.com/booking/hotel.seam?cid=50826
                              
                              http://demo.flamingo.exadel.com/booking/book.seam?cid=50826
                              
                              http://demo.flamingo.exadel.com/booking/confirm.seam?cid=50826
                              
                              http://demo.flamingo.exadel.com/booking/main.seam?cid=50826



                              Mine is like this:


                              http://localhost:8080/BETS/TestManageEquipment.seam
                              
                              http://localhost:8080/BETS/TestBackButton2.seam?cid=5

                              • 27. Re: Help with back button
                                gonorrhea

                                I just tried this as well in my SFSB:


                                @Observer("org.jboss.seam.conversationDestroyed")
                                     public void destroyConversation() {
                                          log.info("begin destroyConversation()");
                                          Conversation c = Conversation.instance();
                                          log.info(String.format("id: %s; isLongRunning %s; viewId: %s", c
                                                               .getId(), c.isLongRunning(), c.getViewId()));
                                     }



                                And that event is not being raised (I checked the org.jboss.seam.core.Manager source code and there's no reference to conversationDestroyed in that class).

                                • 28. Re: Help with back button
                                  gonorrhea

                                  Ok so now I added (pre-pended) a page to the LRC.  User clicks a4j:commandButton to submit form and advance to the original first page.


                                  At this point there is a LRC already.


                                  http://localhost:8080/BETS/TestManageEquipment.seam?cid=13



                                  before there was no cid=xx at the end of the URL.


                                  Now what happens is the destroy() method of the SFSB is not being executed when I click browser back button.


                                  URL looks like this after back button click:


                                  http://localhost:8080/BETS/TestManageEquipment.seam?cid=13



                                  And the form data is erased (same behavior from UI perspective).  The destroy() method is not called and endConversation is not observed.


                                  Wow, so much for the back button just works in Seam.  b.s.

                                  • 29. Re: Help with back button
                                    gonorrhea

                                    A similar page in hotel booking is main.xhtml which uses a4j:commandButton to retrieve the list of hotels and reRender the results in the UI.


                                    I have not been able to figure out why that page does not have the back button problem but mine does...


                                    In main.xhtml, they are using s:link in the dataTable to link to the next page (HTTP GET, not HTTP POST like mine). 


                                    Navigation is specified in pages.xml as follows:


                                    <page view-id="/main.xhtml" 
                                              login-required="true">
                                        
                                            <navigation from-action="#{hotelBooking.selectHotel(hot)}">
                                                <redirect view-id="/hotel.xhtml"/>
                                            </navigation>
                                            
                                            <navigation from-action="#{bookingList.cancel}">
                                                <redirect/>
                                            </navigation>
                                            
                                        </page>



                                    In my case I am returning a String for the next page to redirect to.  I imagine that has the same effect as specifying the redirect in the pages.xml for a particular page/action.