12 Replies Latest reply on Oct 31, 2011 8:24 AM by captainvoid

    Seam Faces InputContainer

    captainvoid

      Hi,
      has anybody successfully used the InputContainer component that Seam Faces provides?
      I just can't get it to work. The validation message never shows up and the automatic wiring of the label and the input text component does not seem to work (JSF warning).


      Here is my component named fieldRow:


      <?xml version="1.0" encoding="UTF-8" ?>
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
           xmlns:composite="http://java.sun.com/jsf/composite"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:s="http://jboss.org/seam/faces"
           xmlns:ui="http://java.sun.com/jsf/facelets">
      
           <composite:interface componentType="org.jboss.seam.faces.InputContainer">
                <composite:attribute name="label" required="true" />
           </composite:interface>
      
      
           <composite:implementation>
                <h:panelGroup layout="block" styleClass="fieldRow">
                     <h:outputLabel id="label" 
                          value="#{cc.attrs.label}"
                          styleClass="fieldRowLabel #{cc.attrs.invalid ? 'invalid-field' : ''} 
                                         #{cc.attrs.required ? 'required' : ''}">
                     </h:outputLabel>
                     <h:panelGroup layout="block"
                               styleClass="fieldRowValue #{cc.attrs.invalid ? 'invalidField' : ''}">
                          <composite:insertChildren />
                     </h:panelGroup>
                     <h:panelGroup layout="block" styleClass="errorBox">
                          <h:message id="message" />
                     </h:panelGroup>
                </h:panelGroup>
           </composite:implementation>
      </ui:composition>
      


      And that's how I use it:



      <txe:fieldRow label="#{messages['login.username']}">
           <h:inputText id="name" 
                required="true"
                value="#{credentials.username}" />
      </txe:fieldRow>
      
      


      The rendered html after a postback leaving the text field empty (validation error):



      <div class="fieldRow">
           <label class="fieldRowLabel invalid-field required" 
                for="login_j_idt35_login_j_idt35_name" 
                id="login_j_idt35_label">Username</label>
           <div class="fieldRowValue invalidField">
                <input type="text" name="login_j_idt35_name" id="login_j_idt35_name">
           </div>
           <div class="errorBox">
                <span id="login_j_idt35_message"></span>
           </div>
      </div>
      



      and in the server log:



      24-oct-2011 17:41:18 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer getForComponent
      ADVERTENCIA: No se encuentra el componente con ID login_j_idt35_name en la vista.
      



      So it seems like that the invalid attribute of the component is correctly set, but the message is not rendered. I don't know how to interpret the server warning...


      I'm using Seam 3.0.0 Final and JSF 2.0.


      Any ideas?
      Thanks a lot for help!!


        • 1. Re: Seam Faces InputContainer
          lightguard

          Definitely try something more current than 3.0.0.Final for Faces.

          • 2. Re: Seam Faces InputContainer
            hantsy

            I have encountered another problem, the required mark was always displayed in some pages.
            But in other pages, it displayed correctly.


            I do not know if the outer UI component affected it.


            • 3. Re: Seam Faces InputContainer
              captainvoid

              Ok,
              I've installed Seam 3.1 Beta 4 and now the error message gets rendered correctly and also the wiring of the label seems to work.


              But I ran into the next problem: If I use ajax for validation (f:ajax inside the h:inputText), I get an exception which is probably a bug in Mojarra:


              xhtml:



              <txe:fieldRow id="username" label="#{messages['login.username']}">
                   <h:inputText id="name" 
                             required="true"
                             value="#{credentials.username}" >
                        <f:ajax event="blur"
                             render="username" 
                             execute="@this" /> 
                   </h:inputText>
              </txe:fieldRow>
              




              server log:




              [15:34:13,769] org.jboss.seam.faces.security.SecurityPhaseListener [DEBUG] [] After Restore View event
              [15:34:13,770] com.safelayer.trustedx.console.errors.ErrorController [DEBUG] [] Exception thrown:
              java.lang.ClassCastException: javax.faces.component.StateHolderSaver cannot be cast to [Ljava.lang.Object;
                   at org.ajax4jsf.component.behavior.AjaxBehavior.restoreState(AjaxBehavior.java:343)
                   at javax.faces.component.UIComponentBase.restoreBehaviors(UIComponentBase.java:2056)
                   at javax.faces.component.UIComponentBase.restoreBehaviorsState(UIComponentBase.java:2023)
                   at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1443)
                   at javax.faces.component.UIOutput.restoreState(UIOutput.java:256)
                   at javax.faces.component.UIInput.restoreState(UIInput.java:1379)
                   at com.sun.faces.application.view.StateManagementStrategyImpl$1.visit(StateManagementStrategyImpl.java:265)
                   at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1485)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIForm.visitTree(UIForm.java:335)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1496)
                   at com.sun.faces.component.visit.VisitUtils.doFullNonIteratingVisit(VisitUtils.java:75)
                   at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:257)
                   at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:181)
                   at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
                   at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:448)
                   at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
                   at com.ocpsoft.pretty.faces.application.PrettyViewHandler.restoreView(PrettyViewHandler.java:109)
                   at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:288)
                   at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:288)
                   at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:288)
                   at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:187)
                   at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
                   at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:111)
                   at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:508)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.solder.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:72)
                   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:233)
                   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
                   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
                   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
                   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
                   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
                   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
                   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
                   at java.lang.Thread.run(Unknown Source)
              
              



              The exception makes my form unusable.


              This post http://seamspace.blogspot.com/2011/09/mojarra-in-trouble.html says that downgrading to Mojarra 2.0.2 should solve the problem. I tried it, and the exception went away, but also my richfaces modal panels didn't work any more. So I'm not sure how to handle this situation. Do I really have to downgrade Mojarra? No other workaround?


              • 4. Re: Seam Faces InputContainer
                hantsy

                I have verified this, downgrading the jsf impl and the ajax works.


                I also encountered the modal panel problem...I am boring while I am migrating my application to Seam 3...there is no such an example application like PhotaAlbum(seam 2.2 and richfaces 3.3) to demo Seam 3 and richfaces 4.


                So I avoid to use richfaces component as possible.

                • 5. Re: Seam Faces InputContainer
                  captainvoid

                  Ok,
                  to continue the story, I upgraded to Mojarra 2.1.3 and the ClassCastException disappeared! And my richfaces modal panels are still working!


                  But: It seems that there's still another bug, and it existed since the beginnig but I just didn't notice it: After submitting the whole form with the required text input field empty, the form is displayed again (correct) with the validation message (correct), but the text input is not empty any more..it is assigned the last value it had before throwing a validation error!


                  So this looks like another Mojarra bug: http://java.net/jira/browse/JAVASERVERFACES-1991 which is a blocker by the way..


                  Not sure how to go on..


                  You're right hantsy, very painful migration to Seam 3 and JSF 2.


                  • 6. Re: Seam Faces InputContainer
                    captainvoid

                    Another insight:


                    If I remove the following parameter from my web.xml, the submitted value of the input component does not get lost any more!




                    <context-param>
                         <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
                         <param-value>true</param-value>
                    </context-param>
                    




                    • 7. Re: Seam Faces InputContainer
                      captainvoid

                      Sorry, I have to correct myself.


                      Removing the parameter
                      javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
                      from web.xml, I also put the xhtml of my composite component as plain xhtml, to see if the aforementioned JSF bug really only applies to composite components.


                      Introducing the composite component again, even with javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL not set, the submitted value is lost after postback, no matter if ajax or not.

                      • 8. Re: Seam Faces InputContainer
                        lightguard

                        IMO, Mojarra was pushed out the door way to early. There have been multiple bugs in each release, some of them breaking for component libraries, others for applications. I hope JSF 2.2 and the resulting Mojarra version is less buggy.

                        • 9. Re: Seam Faces InputContainer
                          captainvoid

                          I agree.


                          Or should I give MyFaces a try?
                          I really need composite components with ajax..

                          • 10. Re: Seam Faces InputContainer
                            lightguard

                            Sure, give MyFaces a try, there may be some other small gotchas, but certainly worth trying.

                            • 11. Re: Seam Faces InputContainer
                              bitec

                              Agree to Jason, Mojarra is too buggy, though I have no time to try Myfaces in my project. In the other project (JSF inside OSGI platform like Service Mix) only Myfaces 2.1 worked, not Mojarra. As I watched through the code, Myfaces is very well written, much more understandable than Mojarra...


                              Also some point about composite components in JSF 2.0 - I don't use them at all as they restrict you to wrap the composite component inside naming container and does not use attributes inheritance (in case you extend some existing component). The first case is solved by using old-fashioned facelets snippets together with manually written facelet-taglib (which is not difficult, by the way), the second one can be solved using some jsf components generation framework like Richfaces CDI or Primefaces maven plugin. The latest one allows to extend existing components and generate inherited attributes in facelets taglib.

                              • 12. Re: Seam Faces InputContainer
                                captainvoid

                                I'm doing the same as Anton.
                                No composite components, but good old facelet tags with the taglib.
                                Once Mojarra gets fixed, I can always rewrite the tags as composite components and just change the namespace in the client xhtml.