5 Replies Latest reply on Jun 9, 2011 4:10 AM by piklos

    Seam-faces messages, and @PostConstruct

    piklos

      I use tomcat 7.0.11 and jsf 2 with seam-faces 3.0.1. And Messages api works great, except if you want to add your message from the @PostConstruct mehod. If code



      message.info('My new message')

      is executed anywhere else except the PostContruct method the messages are shown correctly on the page with:



      <h:messages />



      However when message is added in @PostConstruct method messages are just ignored.
      I've tried this with myfaces 2.1.0 and mojara 2.0.3 and mojarra 2.1.1-b04.
      It consistenly fails.


      So am i doing something wrong? Are @PostConstruct method supposed to be able add faces messages or not?


      To be clear, even if i use


      FacesMessages.getCurrentInstance().addMessage(null, new FacesMessage(....))



      In post construct method, it is ignored. So i guess it is not something related to the seam-faces but rather with jsf implementation.


      So maybe this question would be better suited on some jsf forum, but i hoped that someone could maybe inlight me here.


      Thanks in advance.




        • 1. Re: Seam-faces messages, and @PostConstruct
          piklos

          It seems that i found something that could be a source of this behaviour.
          namely if you have messages in your post construct method on a bean,
          your



          <h:messages />



          Must appear after (not before) your first appearence of your bean.


          So if you got a bean with a post construct method like this one:




          public @Model class HelloWorld {
              @PostConstruct
             public void initialize()
             {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("A Message."));
             }
          }



          And a page like this one:




          <h:messages />
          <span style="color: blue;">#{helloWorld.text}</span>
          



          You messages will be empty.


          But if you rearrange your page to look like this:


          <span style="color: blue;">#{helloWorld.text}</span>
          <h:messages />
          



          The messages will be displayed.


          It looks to me as if facelets evaluate everything from top to bottom  really eagerly.
          That why the messages are empty in the first case.


          Please let someone correct me if i am wrong with this.


          Thanks in advance.



          PS. If i am not wrong, than maybe there should be a worn in the documentation about this feature??







          • 2. Re: Seam-faces messages, and @PostConstruct
            lightguard

            I'd be very interested to see what happen if you use an h:ouputText instead of the direct EL output. I bet it works the way you want it to.

            • 3. Re: Seam-faces messages, and @PostConstruct
              piklos

              Yep you are right,
              with


              <h:outputText.../>



              the position is not important.
              Thank you.


              So can somebody give me a link with the explanation of differences between directly using EL and using it through a jsf component?
              I mean,


              <h:outputText style="color: blue; .../>

              gets rendered as




              <span style="color: blue;">...</span>

              (the same html that i put there by hand).
              So just by looking at the ending html there is no difference at all. Yet one works and one doesn't.


              Should i because of this example conclude that whenever i have an option to choose between plane html with EL, and a jsf commponent that will end up the same, that i should always use jsf component??


              Thanks in advance.






              • 4. Re: Seam-faces messages, and @PostConstruct
                lightguard

                Now you're getting into some of the intricacies of JSF and the JSF lifecycle. The problem you're experiencing is that the messages tag will already have it's content by the time you reach RENDER_RESPONSE (typically it's all figured out in INVOKE_APPLICATION, assuming you don't short circuit the lifecycle).


                Your EL output is only being invoked in RENDER_RESPONSE because it's not associated with a JSF component, so the @PostConstruct happens too late to add any messages. The output that's created and sent to the buffer has to be done from top to bottom once the values are determined otherwise your resulting HTML would be messed up. You could verify this with a debugger and getting a handle on the FacesContext and seeing what phase you're in during the @PostConstruct method.


                A good general rule: If you need something to affect the component tree or values in other components, you have to use a component so everything is done in the correct order. If it doesn't matter, then you're fine with the EL output.

                • 5. Re: Seam-faces messages, and @PostConstruct
                  piklos

                  Thanks a lot for a very good explanation.
                  I already messed with the debbuger during my session with this yesterday, and @PostConstruct was indeed called in render response phase.


                  If this forum had a point system, i would have given you maximum points available :)


                  Thanks again.