13 Replies Latest reply on Aug 7, 2007 9:54 AM by rlhr

    Seam 2, pages.xml and pageflow

      After moving to Seam 2, I have a pageflow that goes into infinite loop.

      I have the following pageflow definition:

       <decision name="isItemDefined" expression="#{myFlow.isItemDefined}">
       <transition name="true" to="itemPage"></transition>
       <transition name="false" to="itemSelectionPage"></transition>
       </decision>
      
       <page name="itemSelectionPage" view-id="/flow/itemSelection.xhtml">
       <redirect/>
       <transition name="next" to="itemPage">
       <action expression="#{flow.initItemEntity}" />
       </transition>
       </page>
      


      So when an item is not defined, the expression in the decision node returns false and we go the the itemSelectionPage.
      The view-id of the itemSelectionPage is defined in pages.xml as:

       <page view-id="/flow/itemSelection.xhtml" action="#{flow.itemSelectionOutcome}" />
      
       <page view-id="/flow/*">
       <navigation>
       <rule if-outcome="listA">
       <redirect view-id="/flow/A/itemSelection.xhtml"/>
       </rule>
       <rule if-outcome="listB">
       <redirect view-id="/flow/B/itemSelection.xhtml"/>
       </rule>
       </navigation>
       </page>
      


      The itemSelectionOutcome returns the type of list (listA or listB) to show.

      Since moving to Seam 2, there is an infinite loop somewhere and flow.itemSelectionOutcome is called again and again.

      If I let de definition related to <page view-id="/flow/*"> in the faces-config.xml file, the same thing happen.

      I'm going to investigate, but if someone knows what's going on, I'll be glad to know.

      Regards,

      Richard


        • 1. Re: Seam 2, pages.xml and pageflow

          I'd appreciate any help to debug this problem.
          Maybe I'd doing something wrong... Where should I put a breakpoint in Seam to get a chance to understand while I get into that loop?

          • 2. Re: Seam 2, pages.xml and pageflow
            gavin.king

            SeamNavigationHandler perhaps.

            • 3. Re: Seam 2, pages.xml and pageflow

              I still don't understand why it is not working, but here is what I found out.

              After the transition (false), we go to the page /flow/itemSelection.xhtml

              That page is defined on pages.xml as:

              <page view-id="/flow/itemSelection.xhtml" action="#{flow.itemSelectionOutcome}" />
              


              The action is triggered and the outcome of this action is "listA"

              I end up in the "navigate" method of Pages.java which is defined as:

               public boolean navigate(FacesContext context, String actionExpression, String actionOutcomeValue)
               {
               String viewId = getViewId(context);
               if (viewId!=null)
               {
               List<Page> stack = getPageStack(viewId);
               for (int i=stack.size()-1; i>=0; i--)
               {
               Page page = stack.get(i);
               Navigation navigation = page.getNavigations().get(actionExpression);
               if (navigation==null)
               {
               navigation = page.getDefaultNavigation();
               }
              
               if ( navigation!=null && navigation.navigate(context, actionOutcomeValue) ) return true;
              
               }
               }
               return false;
               }
              


              The parameters are:

              actionExpression: #{flow.itemSelectionOutcome}
              actionOutcomeValue: "listA"
              


              So far so good, I believe.

              String viewId = getViewId(context) returns "/flow/itemSelection.xhtml" which is correct as well.

              Nevertheless, when the following is performed:

              Navigation navigation = page.getNavigations().get(actionExpression);
              


              navigation is null! No navigation rule is found, so the defaultNavigation is selected and is null as well.

              So I don't understand why is that.

              So instead of

              <page view-id="/flow/itemSelection.xhtml" action="#{flow.itemSelectionOutcome}" />
              
              <page view-id="/flow/*">
               <navigation>
               <rule if-outcome="listA">
               <redirect view-id="/flow/A/itemSelection.xhtml"/>
               </rule>
               <rule if-outcome="listB">
               <redirect view-id="/flow/B/itemSelection.xhtml"/>
               </rule>
               </navigation>
              </page>
              


              I changed to:

              <page view-id="/flow/itemSelection.xhtml" action="#{flow.itemSelectionOutcome}">
               <navigation>
               <rule if-outcome="listA">
               <redirect view-id="/flow/A/itemSelection.xhtml"/>
               </rule>
               <rule if-outcome="listB">
               <redirect view-id="/flow/B/itemSelection.xhtml"/>
               </rule>
               </navigation>
              </page>
              


              But this leads to the same problem.

              Is there anything wrong in the what I'm doing? I believe this should work.

              Richard

              • 4. Re: Seam 2, pages.xml and pageflow

                So I finally fixed my problem. I had to use:

                <page view-id="/flow/itemSelection.xhtml">
                 <navigation evaluate="#{flow.itemSelectionOutcome}">
                 <rule if-outcome="listA">
                 <redirect view-id="/flow/A/itemSelection.xhtml"/>
                 </rule>
                 <rule if-outcome="listB">
                 <redirect view-id="/flow/B/itemSelection.xhtml"/>
                 </rule>
                 </navigation>
                </page>
                


                I guess there are quite few changes to make to go from Seam 1.2 to 2.0 but I must say that the navigation model then becomes much cleaner :)


                • 5. Re: Seam 2, pages.xml and pageflow

                  So I'm still struggling with that issue. I created a small example based on the numberguess example that reproduce the problem (zip file available if needed).

                  I have the following classes:

                  @Name("user")
                  @Scope(ScopeType.CONVERSATION)
                  public class User implements Serializable {
                  
                   private String pet;
                  
                   public String getPet() {
                   return pet;
                   }
                  
                   public void setPet(String pet) {
                   this.pet = pet;
                   }
                  }
                  


                  @Name("navigation")
                  @Scope(ScopeType.CONVERSATION)
                  public class Navigation implements Serializable {
                  
                   @In(required=true)
                   User user;
                  
                   @Logger
                   private Log log;
                  
                   public String animalOutcome(){
                   if (user == null){
                   return "Dog"; // Just to make sure we don't return null
                   }
                   log.info("********* Outcome: " + user.getPet());
                   return user.getPet();
                   }
                  
                   public User getUser() {
                   return user;
                   }
                  
                   public void setUser(User user) {
                   this.user = user;
                   }
                  }
                  


                  @Name("animals")
                  public class AnimalList
                  {
                  
                   private List<String> animals;
                  
                   @Unwrap
                   public List<String> unwrap()
                   {
                   if (animals == null)
                   {
                   animals = new ArrayList<String>();
                   animals.add("Dog");
                   animals.add("Cat");
                   animals.add("Goldfish");
                   animals.add("Rabbit");
                   animals.add("Snake");
                   animals.add("Parrot");
                   }
                   return animals;
                   }
                  }
                  


                  Pages.xhtml is defined as followed:

                  <pages xmlns="http://jboss.com/products/seam/pages"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd">
                  
                   <page view-id="/pageOne.xhtml">
                   <begin-conversation join="true" pageflow="navigation" />
                   </page>
                  
                   <page view-id="/animalPage.xhtml" action="#{navigation.animalOutcome}">
                   <navigation>
                   <rule if-outcome="Dog">
                   <redirect view-id="/animal/dog.xhtml"/>
                   </rule>
                   <rule if-outcome="Cat">
                   <redirect view-id="/animal/cat.xhtml"/>
                   </rule>
                   <rule if-outcome="Goldfish">
                   <redirect view-id="/animal/goldfish.xhtml"/>
                   </rule>
                   <rule if-outcome="Rabbit">
                   <redirect view-id="/animal/rabbit.xhtml"/>
                   </rule>
                   <rule if-outcome="Snake">
                   <redirect view-id="/animal/snake.xhtml"/>
                   </rule>
                   <rule if-outcome="Parrot">
                   <redirect view-id="/animal/parrot.xhtml"/>
                   </rule>
                   </navigation>
                   </page>
                  
                  </pages>
                  


                  The pageflow is defined as:

                  <pageflow-definition
                   xmlns="http://jboss.com/products/seam/pageflow"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://jboss.com/products/seam/pageflow http://jboss.com/products/seam/pageflow-2.0.xsd"
                   name="navigation">
                  
                   <start-page name="displayChoice" view-id="/pageOne.xhtml">
                   <redirect/>
                   <transition name="next" to="animalPage" />
                   </start-page>
                  
                   <page name="animalPage" view-id="/animalPage.xhtml">
                   <end-conversation/>
                   <redirect/>
                   </page>
                  
                  </pageflow-definition>
                  


                  And finally the pageOne.xhtml:

                  <html xmlns="http://www.w3.org/1999/xhtml"
                   xmlns:c="http://java.sun.com/jstl/core"
                   xmlns:ui="http://java.sun.com/jsf/facelets"
                   xmlns:h="http://java.sun.com/jsf/html"
                   xmlns:f="http://java.sun.com/jsf/core"
                   xmlns:s="http://jboss.com/products/seam/taglib">
                  
                   <head>
                   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                   <title>Test Navigation</title>
                   </head>
                  
                   <body>
                   <div id="container">
                   <h3>Choose an animal</h3>
                   <h:form>
                   <h:selectOneMenu value="#{user.pet}">
                   <s:selectItems value="#{animals}" var="animal" label="#{animal}" noSelectionLabel="Select your pet"/>
                   </h:selectOneMenu>
                  
                   <h:commandButton value="Go To Pet Page" action="next" />
                   </h:form>
                   </div>
                   </body>
                  </html>
                  


                  When I select an animal, I get the following stacktrace:

                  INFO: Added Library from: jar:file:/C:/Jboss/jboss-4.2.0.GA/server/default/tmp/d
                  eploy/tmp50163navigation.ear-contents/navigation-exp.war/WEB-INF/lib/jsf-facelet
                  s.jar!/META-INF/jstl-core.taglib.xml
                  13:23:07,046 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,218 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,281 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,359 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,437 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,515 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,609 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,687 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,781 INFO [Navigation] ********* Outcome: Cat
                  13:23:07,859 INFO [Navigation] ********* Outcome: Cat
                  


                  This is the stacktrace using firefox (FF detects the loop and stop the recursion). On IE, the loop never ends.

                  I tried to debug but I didn't really find where the problem lies. I also tried to change the pages.xml definition and played around quite bit.
                  If I move the outcome definition in faces-config.xml, I get the same problem. That problem occurs only with Seam 2 (Seam 1.2.2 works fine).

                  So as a conclusion, I'm stuck :)
                  Do I do anything wrong? Is that a bug?

                  If someone want to code, I can upload a zip of the files somewhere.

                  Thanks.

                  Richard

                  • 6. Re: Seam 2, pages.xml and pageflow
                    pmuir

                    I think you want to use evaluate on navigation on navigation rather than action on page.

                    • 7. Re: Seam 2, pages.xml and pageflow

                      Thanks Pete. I actually tries all the following variant in pages.xml with no success:

                      1:

                      <page view-id="/animalPage.xhtml">
                       <navigation evaluate="#{navigation.outcome}">
                      
                      ...
                      


                      where #{navigation.outcome} returns outcome

                      -> redirection to /animalPage.xhtml (which doesn't exist) because evaluate EL expression is never called

                      2:
                      <page view-id="/animalPage.xhtml" action="#{navigation.animalOutcome}">
                       <navigation evaluate="#{navigation.outcome}">
                      ...
                      


                      where #{navigation.animalOutcome} returns void and #{navigation.outcome} returns outcome
                      -> We enter a loop where action expression is called then evaluate expression is called, etc....

                      3:
                      <page view-id="/animalPage.xhtml" action="#{navigation.animalOutcome}">
                       <navigation from-action="#{navigation.animalOutcome}">
                      ...
                      


                      where #{navigation.animalOutcome} returns outcome

                      -> We enter a loop where action expression is called indefinitely

                      4:
                      <page view-id="/animalPage.xhtml" action="#{navigation.animalOutcome}">
                       <navigation>
                      ...
                      


                      where #{navigation.animalOutcome} returns outcome

                      -> We enter a loop where action expression is called indefinitely

                      I will try to debug each situation to find out what's going on. I did in one case without success. Maybe other case will help me understand better where lies the problem.


                      • 8. Re: Seam 2, pages.xml and pageflow

                        I forgot one case:

                        5:

                        <page view-id="/animalPage.xhtml" action="#{navigation.animalOutcome}">
                         <navigation evaluate="#{navigation.outcome}">
                        ...
                        


                        where #{navigation.animalOutcome} returns outcome and #{navigation.outcome} returns outcome

                        -> We enter a loop where action is called followed by evaluate,....

                        • 9. Re: Seam 2, pages.xml and pageflow
                          pmuir

                          Yes, ok I see the problem. If you want me to take a look I can (no guarantees on when), usual rules applies - upload a simple app build against CVS, deployable onto a clean install of JBoss AS 4.2, use an HSQL database and import.sql for test data, provide instructions on how to replicate.

                          • 10. Re: Seam 2, pages.xml and pageflow

                            I uploaded a very simple app built from a seam example.
                            No need for database setup.
                            There is a readme file explaining what to do.
                            But in short, just unzip the navigation.zip from in http://www.jboss.com/wiki/Wiki.jsp?page=JBossSeam into the examples directory of Seam 2.0.Beta and build it as any example.

                            Let me know of you have any question. If you want me to give some help, let me know where to look at. I must admit that I didn't really find where the problem is so far...

                            • 11. Re: Seam 2, pages.xml and pageflow

                              Hi Pete,

                              Did you get time to take a look at this?
                              I really need this to work or at least to have a workaround. I'm willing to look into it but I'll need some hints. If you have an idea what the problem is and what need to be done, I'll be happy to implements a fix and test it, then at least you guys have a quick fix for now and I can move forward with that.

                              Of course, no pressure :)

                              Richard

                              • 12. Re: Seam 2, pages.xml and pageflow
                                pmuir

                                Yes, I've looked at it. Can you file a JIRA issue, as I want to get Gavin to look at it as well. Thanks!

                                • 13. Re: Seam 2, pages.xml and pageflow