ICEfaces
  1. ICEfaces
  2. ICE-5200

FileUpload in Spring Webflow can't restore state

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.8.2
    • Fix Version/s: 1.8.2a, 1.8.2-EE-GA_P02
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEFaces FileUpload + Spring Webflow

      Description

      Using FileUpload in a Spring application fails during the FileUpload itself with an error indicating the software can't restore the view, whatever the view is.

      It turns out that ICEFaces state saving is not actually invoked in Spring applications. Looking at the code in Spring, Spring doesn't delegate state saving calls to the delegate instance unless the request is deemed not to be a Spring request, and this is established by checking if there is a RequestContext object ThreadLocal defined, and this is setup in the resume or start method of FlowExecutorImpl.

      Here's a stack trace showing the execution path to the point where the RequestContext is established as a ThreadLocal. The entry point to the Spring Webflow applications is through the MainServlet and then goes back into the Spring framework via the SwfLifecycleExecutor.

      at org.springframework.webflow.execution.RequestContextHolder.setRequestContext(RequestContextHolder.java:40)
      at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:218)
      at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)
      at com.icesoft.faces.webapp.http.core.FlowExecutorUtil.launchExecution(FlowExecutorUtil.java:90)
      at com.icesoft.faces.webapp.http.core.SwfLifecycleExecutor.launchExecution(SwfLifecycleExecutor.java:134)
      at com.icesoft.faces.webapp.http.core.SwfLifecycleExecutor.apply(SwfLifecycleExecutor.java:57)
      at com.icesoft.faces.context.View$2$1.respond(View.java:48)
      at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:201)
      at com.icesoft.faces.context.View$2.serve(View.java:77)
      at com.icesoft.faces.context.View.servePage(View.java:149)
      at com.icesoft.faces.webapp.http.core.MultiViewServer.service(MultiViewServer.java:79)
      at com.icesoft.faces.webapp.http.common.ServerProxy.service(ServerProxy.java:11)
      at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet$4.service(MainSessionBoundServlet.java:149)
      at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
      at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:60)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:148)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)
      at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)


      For the sake of interest, views are rendered by the SpringFramework treating the JSF Views as a certain type of renderable.

      at com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:284)
      at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:159)
      at org.springframework.faces.webflow.FlowViewHandler.renderView(FlowViewHandler.java:92)
      at org.springframework.faces.webflow.JsfView.render(JsfView.java:94)
      at org.springframework.webflow.engine.ViewState.render(ViewState.java:245)
      at org.springframework.webflow.engine.ViewState.resume(ViewState.java:204)
      at org.springframework.webflow.engine.Flow.resume(Flow.java:545)
      at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:262)
      at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:163)
      at com.icesoft.faces.webapp.http.core.FlowExecutorUtil.resumeExecution(FlowExecutorUtil.java:86)
      at com.icesoft.faces.webapp.http.core.SwfLifecycleExecutor.resumeExecution(SwfLifecycleExecutor.java:129)
      at com.icesoft.faces.webapp.http.core.SwfLifecycleExecutor.apply(SwfLifecycleExecutor.java:55)
      at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
      at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74)
      at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
      at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
      at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:60)
      at com.icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:148)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)


      When a FileUpload request is processed a lifecycle event is generated by the upload process in order to update the Upload progress page. Since the PathDispatcher matches the path of the FileUploadServlet execution goes down that route and doesn't have the Spring path portions in it, therefore a Spring webflow isn't resumed. Since the Spring Webflow isn't resumed, the StateSaving code executed when running the lifecycle is delegated to our StateSaving implementation which is looking for a viewRoot in the State Maps in the session.

      at com.icesoft.faces.webapp.http.core.UploadServer$2.servlet(UploadServer.java:127)
      at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.detectEnvironment(ServletRequestResponse.java:262)
      at com.icesoft.faces.webapp.http.core.UploadServer.service(UploadServer.java:69)
      at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
      at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:60)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:148)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)


      Since we haven't been involved in saving the state at any time in the past, there isn't any copy of the ViewRoot in the Session when this attempt is made, hence the error.

        Activity

        Greg Dick created issue -
        Greg Dick made changes -
        Field Original Value New Value
        Assignee Greg Dick [ greg.dick ]
        Hide
        Greg Dick added a comment -

        The way that ICEFaces integrates with Spring Webflow is as follows:

        Requests to ICEFaces, and even requests that normally are mapped to Spring all go to ICEFaces. ICEfaces has an assortment of Handler classes mapped to handle requests and ICEFaces handles the request. If a Spring request, control is passed to the SwfLifecycleExecutor which either starts a new flow or resumes execution of an old one.

        Control then passes to Spring, which executes a JSF lifecycle and then returns control to ICEFaces through the VIewHandler instance which is used to render the page. The Spring state saving instance does not delegate to any other StateSaving class if the request is a Spring mapped request, which is why ICEFaces StateSaving never gets invoked, even though it is configured by default.

        The FileUpload mechanism runs a JSF lifecycle to render the progress bar at intervals. These lifecycles don't have the Spring ThreadLocal necessary for Spring to detect a webflow request, so they delegate to ICEFaces state saving. The solution to this is to launch the progress lifecycle via Spring webflow if a Spring environment is detected. This should be ok, no state transition should be executed because there will be no result from the webflow execution.

        Show
        Greg Dick added a comment - The way that ICEFaces integrates with Spring Webflow is as follows: Requests to ICEFaces, and even requests that normally are mapped to Spring all go to ICEFaces. ICEfaces has an assortment of Handler classes mapped to handle requests and ICEFaces handles the request. If a Spring request, control is passed to the SwfLifecycleExecutor which either starts a new flow or resumes execution of an old one. Control then passes to Spring, which executes a JSF lifecycle and then returns control to ICEFaces through the VIewHandler instance which is used to render the page. The Spring state saving instance does not delegate to any other StateSaving class if the request is a Spring mapped request, which is why ICEFaces StateSaving never gets invoked, even though it is configured by default. The FileUpload mechanism runs a JSF lifecycle to render the progress bar at intervals. These lifecycles don't have the Spring ThreadLocal necessary for Spring to detect a webflow request, so they delegate to ICEFaces state saving. The solution to this is to launch the progress lifecycle via Spring webflow if a Spring environment is detected. This should be ok, no state transition should be executed because there will be no result from the webflow execution.
        Arran Mccullough made changes -
        Salesforce Case [5007000000A7jdQ]
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #20212 Wed Jan 13 13:25:59 MST 2010 greg.dick ICE-5200 Removed unnecessary and quietly failing check for formClientId
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/component/inputfile/FileUploadPhaseListener.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #20213 Wed Jan 13 13:26:56 MST 2010 greg.dick ICE-5200 launch spring webflow via executor if spring environment rather than calling PSF.executeAndRender
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/http/core/UploadServer.java
        Hide
        Greg Dick added a comment -

        The code now executes JSF lifecycles via Spring Webflow if Webflow is detected.

        Show
        Greg Dick added a comment - The code now executes JSF lifecycles via Spring Webflow if Webflow is detected.
        Greg Dick made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 1.8.2-EE-GA_P02 [ 10226 ]
        Fix Version/s 1.8.2a [ 10229 ]
        Resolution Fixed [ 1 ]
        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Assignee Greg Dick [ greg.dick ]
        Ken Fyten made changes -
        Resolution Fixed [ 1 ]
        Status Closed [ 6 ] Reopened [ 4 ]
        Assignee Priority P1
        Ken Fyten made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Assignee Priority P1
        Resolution Fixed [ 1 ]
        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Greg Dick
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: