Re: issue 1826

From: Ed Burns <>
Date: Mon, 11 Oct 2010 08:09:23 -0700

Forwarding to dev_at_javaserverfaces.

>>>>> On Sat, 9 Oct 2010 23:37:07 -0700, Sheetal Vartak <> said:

SV> Hi Ed/Roger, 1826 is regarding the Acid test (4 tests) that Richard
SV> Kennard wrote. Our RI passes 3. The one that's failing produces a
SV> stack trace as follows :

SV> [#|2010-10-07T14:26:11.910-0700|WARNING|glassfish3.1||_ThreadID=81;_ThreadName=http-thread-pool-8080(1);|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
SV> java.lang.ClassCastException: com.sun.faces.application.view.StateHolderSaver cannot be cast to [Ljava.lang.Object;
SV> at javax.faces.component.UIOutput.restoreState(
SV> at com.sun.faces.application.view.StateManagementStrategyImpl$1.visit(
SV> at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(
SV> at javax.faces.component.UIComponent.visitTree(
SV> at javax.faces.component.UIComponent.visitTree(
SV> at javax.faces.component.UIComponent.visitTree(
SV> at javax.faces.component.UIForm.visitTree(
SV> at javax.faces.component.UIComponent.visitTree(
SV> at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(
SV> at com.sun.faces.application.StateManagerImpl.restoreView(
SV> at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(
SV> at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(
SV> at com.sun.faces.application.view.MultiViewHandler.restoreView(
SV> at com.sun.faces.lifecycle.RestoreViewPhase.execute(
SV> at com.sun.faces.lifecycle.Phase.doPhase(
SV> at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(
SV> at com.sun.faces.lifecycle.LifecycleImpl.execute(
SV> at javax.faces.webapp.FacesServlet.service(

SV> Now in the case where a component is dynamically added (subscribed
SV> to PreRenderViewEvent), things work just fine. Ed, your devtest that
SV> you added for 1757 does a dynamic add. Hence you have'nt seen this
SV> exception. It can be reproduced with Richard's acid test. He is
SV> removing a component from getChildren() and adding it
SV> back. Basically trying to toggle the order of the children in a
SV> form:

SV> UIComponent component = getChildren().remove( 0 );
SV> getChildren().add( component );

SV> What's happening is that the stateObj in this case for the UIOutput
SV> component is an instance of
SV> com.sun.faces.application.view.StateHolderSaver and there is no code
SV> to handle this situation during restoreState(). There is a check to
SV> see if the stateObj is an instance of
SV> javax.faces.component.StateHolderSaver, but there is no relation
SV> between the 2 except for the fact that the classes have identical
SV> code in them. Why is javax.faces.component.StateHolderSaver not a
SV> public class and why do we have another class
SV> (com.sun.faces.application.view.StateHolderSaver) doing the same
SV> thing ?

SV> I see that code was introduced in
SV> StateManagementStrategyImpl.saveComponentState() as follows :

SV> if (stateContext.componentAddedDynamically(c)) {
SV> stateObj = new StateHolderSaver(ctx, c); //This is com.sun.faces.application.view.StateHolderSaver
SV> // ensure it's in the addList.
SV> Map<String, ComponentStruct> dynamicAdds = stateContext.getDynamicAdds();
SV> assert(null != dynamicAdds);
SV> String clientId = c.getClientId(ctx);
SV> if (!dynamicAdds.containsKey(clientId)) {
SV> ComponentStruct toAdd = new ComponentStruct();
SV> toAdd.absorbComponent(ctx, c);
SV> dynamicAdds.put(clientId, toAdd);
SV> }
SV> } else {... }

SV> But there is no code to restore state if the stateObj is of type
SV> com.sun.faces.application.view.StateHolderSaver.

SV> Any clues/comments?

| | office: +1 407 458 0017
| homepage:               |