8 Replies Latest reply on Apr 22, 2009 3:22 PM by skidvd.seamframework.abilsoft.com

    FaceMessages confusion - messages not displayed

    skidvd.seamframework.abilsoft.com

      Hello,


      I am confused as I am not able to get a FacesMessage to be displayed in certain circumstances via org.jboss.seam.facesMessages.addToControl.  Yet, FacesContext.getCurrentInstance().addMessage() works, in the exact same conditions location?


      This works - i.e. the FaceMessage is diaplyed as desired



               FacesContext.getCurrentInstance().addMessage( 
                         "discoveryListTable", 
                         new FacesMessage( FacesMessage.SEVERITY_ERROR,
                              "Error while retrieving discoveryLists: " + e,
                              "Error while retrieving discoveryLists: " + e     ) );




      This does NOT work (in the same location) - i.e. the FacesMessage is never displayed (global also checked...)


      |            facesMessages.addToControl( "discoveryListTable",
                                      StatusMessage.Severity.ERROR,
                                      "Error while retrieving discoveryLists: " + e, 
                                      (Object[]) null );|



      I'm not sure why one works when the other does not.  I have been researching many forum posts such as the following.....


      http://www.seamframework.org/Community/BugInFacesMessagePropagation
      http://www.seamframework.org/Community/TroubleWithFacesMessages
      http://www.seamframework.org/Community/FacesMessagesArentPropogatedAcrossRedirect


      These seem to indicate similar problems.  However, as my application is a bit different in that navigation via navigation.xml and pages.xml is not involved; I'd like to make sure I'm not doing something wrong, or that there is not a better way....


      I have also found:


      https://jira.jboss.org/jira/browse/JBSEAM-1855


      But again, I am not sure if this is the exact problem I am facing - although it certainly seems related.


      My application has the following:



                       <a4j:outputPanel id="contentPanel" style="position: relative; display: block; width: 100%; padding-top: 3px;">
                           <rich:panel id="main">
                               <f:facet name="header">
                                <h:outputText value="#{mainController.contentTitle}"/>
                           </f:facet>
      
                           <a4j:include viewId="#{mainController.contentView}" id="contentView"/>
                       </rich:panel>
                   </a4j:outputPanel>



      This contents of this outputPanel  are controlled via the referenced mainController component which is user-set via menu selection such as the following:



      <rich:panelMenuItem label="Discovery List" action="#{mainController.setContentView( 'discoveryList' )}" reRender="contentPanel" status="mainStatus">
                                <rich:toolTip value="#{mainController.getContentTooltip( 'discoveryList' )}"/>
                           </rich:panelMenuItem>



      All of the above works just fine and the contentPanel gets reRender-ed with the proper content in response to the user's menu selection as desired. 


      The problem occurs in that the selected content invokes a Factory method similar to the following:



             @Factory( "discoveryLists" )
             public List<DiscoveryList> getDiscoveryLists()
             {
                  // .....   details omitted for brevity
           }
           catch( Exception e )
           {
               log.error( "Error while retrieving discoveryLists", e );
               //e.printStackTrace();
               /*
               FacesContext.getCurrentInstance().addMessage( 
                         "discoveryListTable", 
                         new FacesMessage( FacesMessage.SEVERITY_ERROR,
                              "Error while retrieving discoveryLists: " + e,
                              "Error while retrieving discoveryLists: " + e     ) );
                */
                  facesMessages.addToControl( "discoveryListTable",
                                      StatusMessage.Severity.ERROR,
                                      "Error while retrieving discoveryLists: " + e, 
                                      (Object[]) null );
           }
           
           return discoveryLists;
          }
      
      



      If the Factory method encounters problems, I would like to display an appropriate message to the user.  Notice the commented out FacesContext.getCurrentInstance().addMessage() call - this is the one that works and I have toggled back and forth between that one and the included facesMessages.addToControl() call for my testing.


      So the problem is that the facesMessages.addToControl() call will not produce the desired(any) FacesMessage which is to be displayed via



             <a4j:outputPanel ajaxRendered="true">
                 <rich:messages id="discoveryListMsgs" globalOnly="false" tooltip="true" infoClass="info" warnClass="warning" errorClass="error"/>
             </a4j:outputPanel>



      Another curious part of this, is that the FacesMessage will be displayed upon subsequent refreshes of the contentPanel (assuming the error condition remains in place) - this is to say that the facesMessages.addToControl() only fails to produce the desired FacesMessage for the intial display of the user selected contentPanel contents.  I assume this has something to do with the view tree's existence and population.


      I would definitely like to understand why the one call works (in all conditions) and the other does not work in any other than refresh conditions.  I would also like to know if there is a better way to approach this sort of situation?  Any and all insights, suggestions and ideas are welcome.  IF nothing else, should I just use the FacesContext.getCurrentInstance().addMessage() and not worry about it?  I prefer to stick with the Seam facesMessages.addToControl() varient , but can control my curiousity if the former is the probper method in this circumstance - in this case I'd really like to understand why so that I can avoid this confusion in future situations?


      TIA!