Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 3.0.1
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      Tomcat 7.0.5, Weld 1.1.0, various versions of Mojarra and MyFaces tested

    • Affects:
      Compatibility/Configuration

      Description

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

      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)
      

      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?

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                chkal Christian Kaltepoth
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated: