[seam-issues] [JBoss JIRA] Created: (SEAMFACES-167) UIValidateForm's state saving doesn't work correctly

Christian Kaltepoth (JIRA) jira-events at lists.jboss.org
Wed Jun 1 11:24:00 EDT 2011


UIValidateForm's state saving doesn't work correctly
----------------------------------------------------

                 Key: SEAMFACES-167
                 URL: https://issues.jboss.org/browse/SEAMFACES-167
             Project: Seam Faces
          Issue Type: Bug
          Components: Validation & Conversion
    Affects Versions: 3.0.1
         Environment: Tomcat 7.0.5, Weld 1.1.0, various versions of Mojarra and MyFaces tested 
            Reporter: Christian Kaltepoth


I'm getting the following exception if I use {{s:validateForm}} on a page:

{code}
java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
	java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
	java.util.HashMap.writeObject(HashMap.java:1001)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:597)
	java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
	java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
	java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
	java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
	java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
	java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
	java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
	java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
	java.util.HashMap.writeObject(HashMap.java:1001)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	java.lang.reflect.Method.invoke(Method.java:597)
	java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
	java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
	java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
	java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
	java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
	com.sun.faces.renderkit.ClientSideStateHelper.doWriteState(ClientSideStateHelper.java:293)
	com.sun.faces.renderkit.ClientSideStateHelper.writeState(ClientSideStateHelper.java:167)
	com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:123)
	com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:155)
	com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:221)
	com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:397)
	com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
	javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
	javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
	com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
	com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
{code}

I'm getting this (or similar) exceptions for the following combinations of JSF implementation and state saving configuration:

* Mojarra <= 2.0.2 (client side state saving)
* MyFaces (all versions, client & server side state saving)

I'm NOT getting this exception with:

* Mojarra <= 2.0.2 (server side state saving)
* Mojarra >= 2.0.3 (client & server side state saving)

The problem seems to be that {{UIValidateForm}} saves a {{Map<String,UIInput>}} to the view state. Older Mojarra versions and MyFaces will try to serialize this map which will fail because {{UIInput}} doesn't implement {{Serializable}}. Newer Mojarra versions are handling maps by processing keys and values individually and seem to correctly detect that {{UIInput}} implements {{StateHolder}}.

However I don't think that a JSF implementation is required to support such situations. I looked at the spec and it only says that the objects written to the state (a map in this case) have to either implement {{Serializable}} or {{StateHolder}} (see 3.2.4.2).

I'm seeing the following options for this problem:

* Keep the current behavior. But this breaks compatibility with older Mojarra versions and all MyFaces versions.
* Replace the map with a list. I think this should work because I saw special handling for lists in both Mojarra and MyFaces. But the spec doesn't enforce this for a JSF implementation.
* Don't store the map in the state at all. I think this should work because the map is always populated with the required values by {{FormValidationFieldProducer}} before the actual validation happens.  

What do you think?

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the seam-issues mailing list