5 Replies Latest reply on Feb 5, 2008 2:28 PM by Viggo Navarsete

    Problem with partual update in a Richfaces portlet

    Viggo Navarsete Expert

      Hi,
      I'm having a very simple Richfaces portlet with one input field and a button. When the button is clicked, another textfield is supposed to be updated with a value from the backing bean. My problem is that when pushing the button, nothing happens (and I've attached a PhaseListener as well, but it doesn't print anything..). So, to the code:

      start.xhtml:

      <f:view contentType="text/html"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:c="http://java.sun.com/jstl/core"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:r="http://richfaces.org/rich">
       <!--a4j:portlet-->
       <html>
       <body>
       <h:form>
       <h:panelGrid columns="3">
       <h:outputText value="Name:" />
       <h:inputText value="#{searchBean.searchString}" />
       <a4j:commandButton value="Say Hello" action="#{searchBean.search}" reRender="searchResult"/>
       </h:panelGrid>
       </h:form>
       <!--a4j:outputPanel layout="none">
       <h:outputText id="searchResult" value="#{searchBean.result}"/>
       </a4j:outputPanel-->
       <a4j:outputPanel ajaxRendered="true">
       <h:outputText id="searchResult" value="#{searchBean.result}"/>
       </a4j:outputPanel>
       </body>
       </html>
       <!--/a4j:portlet-->
      </f:view>


      backing bean:
      package com.test.dashboard;
      
      /**
       *
       * @author viggo
       */
      public class SearchBean {
      
       private String searchString;
       private String result;
      
       public String getSearchString() {
       return searchString;
       }
      
       public void setSearchString(String searchString) {
       this.searchString = searchString;
       }
      
       public String search() {
       result = "Hello " + searchString;
       //return "success";
       return null;
       }
      
       public String getResult() {
       return result;
       }
      
       public void setResult(String result) {
       this.result = result;
       }
      }


      faces-config.xml:
      <?xml version='1.0' encoding='UTF-8'?>
      <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
      
       <managed-bean>
       <description>
       The bean that backs up the Search portlet
       </description>
       <managed-bean-name>searchBean</managed-bean-name>
       <managed-bean-class>com.test.dashboard.SearchBean</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
       </managed-bean>
       <navigation-rule>
       <from-view-id>/jsf/start.xhtml</from-view-id>
       <navigation-case>
       <from-outcome>success</from-outcome>
       <to-view-id>/jsf/start.xhtml</to-view-id>
       </navigation-case>
       </navigation-rule>
       <render-kit>
       <renderer>
       <description>override the viewroot</description>
       <component-family>javax.faces.ViewRoot</component-family>
       <renderer-type>javax.faces.ViewRoot</renderer-type>
       <renderer-class>org.ajax4jsf.portlet.renderkit.portlet.PortletAjaxViewRootRenderer</renderer-class>
       </renderer>
       </render-kit>
       <application>
       <view-handler>
       org.ajax4jsf.portlet.application.PortletViewHandler
       </view-handler>
       <state-manager>
       org.ajax4jsf.portlet.application.PortalStateManager
       </state-manager>
       </application>
       <factory>
       <faces-context-factory>
       org.ajax4jsf.portlet.context.FacesContextFactoryImpl
       </faces-context-factory>
       </factory>
       <lifecycle>
       <phase-listener>com.test.dashboard.util.PhaseTracker</phase-listener>
       </lifecycle>
      </faces-config>


      I have tried all sorts of combination with <a:form> with <h:commandButton> and <a4j:commandButton>. Also <h:form> with <h:commandButton> and <a4j:commandButton>. Also with all kinds of reRender attributes, a4j:outputPanel, and I can't imagine what I haven't tried. I guess I will get some feedback on what kind of phases have been executed, but according to the output, it seems like nothing is printed when I have pushed the button. Could someone please describe a very simple solution I could try to solve my problem?

      And some final questions:
      1. When running AJAX requests using either <a4j:form> or <a4j:commandButton>, I think that the method in the backing bean should always return null. But what about the navigation rules in faces-config.xml, should they be removed to make things work...or what?

      My dependencies: I'm running the 3.1.3.GA of all richfaces libraries on top of JBoss Portal 2.6.3 and JBoss AS 4.2.2.GA. Everything is running on top of jdk 1.5.0_12.

        • 3. Re: Problem with partual update in a Richfaces portlet
          Viggo Navarsete Expert

          I have also had this error message in my log:

          java.lang.IllegalStateException: The window output stream is already used.

          Does anyone know what the reason for this handsome error to occur?

          • 4. Re: Problem with partual update in a Richfaces portlet
            Viggo Navarsete Expert

            With this in my xhtml file:

            <f:view contentType="text/html"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:c="http://java.sun.com/jstl/core"
             xmlns:a4j="http://richfaces.org/a4j"
             xmlns:r="http://richfaces.org/rich">
             <a4j:portlet>
             <html>
             <body>
             <a4j:form>
             <h:panelGrid columns="3">
             <h:outputText value="Name:" />
             <h:inputText value="#{searchBean.searchString}" />
             <a4j:commandButton value="Say Hello" "reRender="searchResult"/>
             </h:panelGrid>
             </a4j:form>
             <h:panelGroup id="searchResult">
             <h:outputText value="#{searchBean.searchString}" />
             </h:panelGroup>
             </body>
             </html>
             </a4j:portlet>
            </f:view>


            everything is working, the searchstring is displayed when pushing the button, but if I change my xhtml to:
            <f:view contentType="text/html"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:c="http://java.sun.com/jstl/core"
             xmlns:a4j="http://richfaces.org/a4j"
             xmlns:r="http://richfaces.org/rich">
             <a4j:portlet>
             <html>
             <body>
             <a4j:form>
             <h:panelGrid columns="3">
             <h:outputText value="Name:" />
             <h:inputText value="#{searchBean.searchString}" />
             <a4j:commandButton value="Say Hello" action="#{searchBean.search}"reRender="searchResult"/>
             </h:panelGrid>
             </a4j:form>
             <h:panelGroup id="searchResult">
             <h:outputText value="#{searchBean.result}" />
             </h:panelGroup>
             </body>
             </html>
             </a4j:portlet>
            </f:view>


            where I've added information to the commandButton to execute a method in my backing bean before presenting the result to the user, and this method in my backing bean:
             public String search() {
             result = "Hello " + searchString;
             //return "success";
             return null;
             }


            (note: I've also getter and setter methods for the #{searchBean.result}" in my backing bean)

            When I push the button I get the following exception
            Caused by: javax.portlet.faces.BridgeException: Error processing render lifecycle
             at org.ajax4jsf.portlet.ExceptionHandlerImpl.processRenderException(ExceptionHandlerImpl.java:31)
             at org.ajax4jsf.portlet.AjaxPortletBridge.doFacesRequest(AjaxPortletBridge.java:211)
             at javax.portlet.faces.GenericFacesPortlet.doFacesDispatch(GenericFacesPortlet.java:142)
             ... 236 more
            Caused by: javax.faces.FacesException: java.lang.IllegalStateException: The window output stream is already used
             at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:306)
             at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
             at org.ajax4jsf.portlet.AbstractAjaxBridge.render(AbstractAjaxBridge.java:118)
             at org.ajax4jsf.portlet.AjaxPortletBridge.doFacesRequest(AjaxPortletBridge.java:187)
             ... 237 more
            Caused by: java.lang.IllegalStateException: The window output stream is already used
             at org.jboss.portal.portlet.invocation.response.FragmentResponse.getWriter(FragmentResponse.java:181)
             at org.jboss.portal.portlet.impl.jsr168.api.RenderResponseImpl.getWriter(RenderResponseImpl.java:118)
             at org.ajax4jsf.portlet.application.PortletViewHandler.renderView(PortletViewHandler.java:185)
             at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
             at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
             ... 240 more

            So, does anyone know what to do when you want to execute a method in the backing bean as part of the AJAX update? I return null from my method, as described in the documentation, but still it doesn't work.