spring-projects / spring-webflow

Spring Web Flow
https://spring.io/projects/spring-webflow
Apache License 2.0
333 stars 235 forks source link

JSF Composite Component causes NPE during deserialization [SWF-1544] #727

Open spring-operator opened 12 years ago

spring-operator commented 12 years ago

Pelz Rutsche opened SWF-1544 and commented

Steps to reproduce (or apply attached patch to issue project #653)

  1. Create composite component that contains a composite:insertFacet or composite:insertChildren
  2. Create a flow with one view-state
  3. Create a view that uses the composite component
  4. Run the application and load the page
  5. Reload the page twice (in the same flow state)

The NPE is thrown during unmarshaling the flow snapshot. Mojarra's Resource implementation tries to obtain a ResourceManager from the current FacesContext. The FacesContext, however, has not been set at this point since FlowFacesContextListener would get notified after a the snapshot is restored.

This issue has already been reported for version 2.2.1 but #653 has been set to "Resolved" as of inability to reproduce.

java.lang.NullPointerException
    at com.sun.faces.application.resource.ResourceImpl.readExternal(ResourceImpl.java:415)
    at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at java.util.ArrayList.readObject(ArrayList.java:593)
        ...
    at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.deserialize(SerializedFlowExecutionSnapshot.java:194)
    at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.unmarshal(SerializedFlowExecutionSnapshot.java:99)
    at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory.restoreExecution(SerializedFlowExecutionSnapshotFactory.java:80)
    at org.springframework.webflow.execution.repository.snapshot.AbstractSnapshottingFlowExecutionRepository.restoreFlowExecution(AbstractSnapshottingFlowExecutionRepository.java:89)
    at org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository.getFlowExecution(DefaultFlowExecutionRepository.java:115)
    at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:168)
    at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
    at org.springframework.faces.webflow.JsfFlowHandlerAdapter.handle(JsfFlowHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        ...

Affects: 2.3.1

Reference URL: http://forum.springsource.org/showthread.php?126554-SWF-2-3-1-JSF-Composite-Component-Not-Working

Attachments:

spring-operator commented 12 years ago

Rossen Stoyanchev commented

An issue project would be much appreciated and help speed up the resolution.

spring-operator commented 12 years ago

Pelz Rutsche commented

Done, I just sent the pull request.

spring-operator commented 12 years ago

Pelz Rutsche commented

Alright, here's the issue project for SWF-1544

spring-operator commented 12 years ago

Rossen Stoyanchev commented

A JSF ResourceImpl is getting serialized and stored with the custom component and it looks like its custom deserialization method (readExternal) relies on FacesContext. However, a FacesContext is not available until the FlowFacesContextLifecycleListener is invoked, which occurs when the FlowExecution is resumed (and after being restored). Arguably a low-level operation such as serialization and de-serialization, which can occur independent of web request should not rely on the presence of a FacesContext.

Tracing back the history of Mojarra, the dependency on FacesContext during deserialization was "fixed" in JAVASERVERFACES-911 but then removed (or perhaps lost) in the very next commit r6845.

Actually, I recall now opening this ticket JAVASERVERFACES-1690. So it looks like this is the same problem actually. The fix version is 2.2 but adding your vote wouldn't hurt.

You can try the patch I added to the issue project in your own application. That'll confirm if the expected fix in Mojarra 2.2 will work.

spring-operator commented 12 years ago

Pelz Rutsche commented

Thanks a lot for the detailed information. I voted for JAVASERVERFACES-1690 and hopefully the fix will make it into the next release. My current workaround uses a Servlet filter which sets up a FacesContext with an empty Lifecycle as I wasn't sure if the bug was in SWF or JSF but I'll try your patch as well.