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

        
_______________________________________________
seam-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/seam-issues

Reply via email to