1 Reply Latest reply on Mar 14, 2007 2:01 PM by Andrew

    Restore state failing with facelets component

    Andrew Apprentice

      I have a component that is created using the facelets tag handler API similar to the ui:component tag. I wasn't having any issue with AjaxAnywhere with it, but with A4J plugged in, I am getting an odd behavior:

      java.lang.ClassCastException: java.lang.String
       at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:947)
       at com.outlooksoft.cpm.livereport.controls.HtmlReportFilterDialog.restoreState(HtmlReportFilterDialog.java:237)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:731)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:722)
       at org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:200)
       at org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:270)
       at org.ajax4jsf.framework.ajax.AjaxStateManager.restoreView(AjaxStateManager.java:83)
       at org.jboss.seam.jsf.SeamStateManager.restoreView(SeamStateManager.java:49)
       at org.ajax4jsf.framework.ajax.AjaxStateManager.restoreView(AjaxStateManager.java:83)
       at org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:231)
       at com.sun.facelets.FaceletViewHandler.restoreView(FaceletViewHandler.java:321)
       at org.ajax4jsf.framework.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:116)
       at org.ajax4jsf.framework.ajax.AjaxViewHandler.restoreView(AjaxViewHandler.java:147)
       at org.jboss.seam.jsf.SeamViewHandler.restoreView(SeamViewHandler.java:64)
       at org.jenia.faces.template.handler.ViewHandler.restoreView(ViewHandler.java:263)
       at com.sun.facelets.FaceletViewHandler.restoreView(FaceletViewHandler.java:321)
       at org.ajax4jsf.framework.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:116)
       at org.ajax4jsf.framework.ajax.AjaxViewHandler.restoreView(AjaxViewHandler.java:147)
       at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:81)
       ...


      My restore and save code:
      @Override
       public Object saveState(FacesContext context)
       {
       return new Object[] {
       super.saveState(context),
       ajaxZone,
       value,
       saveAttachedState(context, onAcceptListener),
       saveAttachedState(context, onCancelListener)
       };
       }
      
       @Override
       public void restoreState(FacesContext context, Object state)
       {
       Object[] array = (Object[])state;
       int index = -1;
       super.restoreState(context, array[++index]);
      
       ajaxZone = (String)array[++index];
       value = array[++index];
       onAcceptListener = (MethodBinding)restoreAttachedState(context, array[++index]);
       onCancelListener = (MethodBinding)restoreAttachedState(context, array[++index]);
       }
      


      When I debug into the code, the state passed into the code is an array with the wrong length (7 instead of the expected 5). "state[0]" was a string instead of an array, its value being "_id172" which doesn't appear anywhere in the generated HTML (and this control doesn't have an auto-generated ID), so it is hard to find out what this state is actually for. Any ideas?

        • 1. Re: Restore state failing with facelets component
          Andrew Apprentice

          Just found it using facelets debugging. The <ui:debug /> was generating:

          <UIDebug hotkey="D" id="_id172" rendered="true" transient="true"/>

          For some reason, this transient component was getting stored into the view state and when attempting to restore, it was getting passed to the wrong component. Any idea why the transient flag was failing to get applied correctly?