Spring Web Flow
  1. Spring Web Flow
  2. SWF-749

Can't place scoped-proxied beans into flow scope

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.2
    • Fix Version/s: 2.1.0.M2
    • Component/s: None
    • Labels:
      None

      Description

      If I create a bean in session scope, and try to assign it to a flow scope var, I get an error, because not all beans in flow scope are serializables. Problem is not only within session scope, as it happens the same with a custom scope. Seems more a problem dealing with CGLIB proxies.

      Defined in AppContex.xml

      <bean id="sesionperson" class="org.springframework.webflow.samples.phonebook.Person" scope="session"
      p:firstName="Peter" p:lastName="Smith">
      <aop:scoped-proxy proxy-target-class="true"/>
      </bean>

      Defined in myFlow.xml

      <var name="flowperson" class="org.springframework.webflow.samples.phonebook.Person"/>
      <view-state id="inicio" model="idContainer">
      <on-render>
      <evaluate expression="sesionperson" result="flowperson" />
      </on-render>
      </view-state>

      The bean implements Serializable

      public class Person implements Serializable {
      ....
      }

      The problem solves if I eliminate <aop:scoped-proxy proxy-target-class="true"/> from the bean definition. I suppose that the proxied bean does not implement Serializable.

      THIS WORKS:

      <bean id="sesionperson" class="org.springframework.webflow.samples.phonebook.Person" scope="session"
      p:firstName="Peter" p:lastName="Smith">
      </bean>

      And the StackTrace

      java.io.NotSerializableException: org.springframework.aop.scope.DefaultScopedObject
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1338)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1146)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
      at java.util.HashMap.writeObject(HashMap.java:1001)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
      at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:416)
      at org.springframework.webflow.core.collection.LocalAttributeMap.writeObject(LocalAttributeMap.java:327)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
      at org.springframework.webflow.engine.impl.FlowSessionImpl.writeExternal(FlowSessionImpl.java:154)
      at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1421)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1390)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
      at java.util.LinkedList.writeObject(LinkedList.java:943)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
      at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
      at org.springframework.webflow.engine.impl.FlowExecutionImpl.writeExternal(FlowExecutionImpl.java:508)
      at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1421)
      at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1390)
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
      at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.serialize(SerializedFlowExecutionSnapshot.java:172)
      at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.<init>(SerializedFlowExecutionSnapshot.java:69)
      at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory.createSnapshot(SerializedFlowExecutionSnapshotFactory.java:70)
      at org.springframework.webflow.execution.repository.snapshot.AbstractSnapshottingFlowExecutionRepository.snapshot(AbstractSnapshottingFlowExecutionRepository.java:75)
      at org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository.putFlowExecution(DefaultFlowExecutionRepository.java:115)
      at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:155)
      at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:173)
      at org.springframework.webflow.mvc.servlet.FlowController.handleRequest(FlowController.java:172)
      at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
      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.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:619)

        Activity

        Hide
        Keith Donald added a comment -

        Adding Juergen to watch list.

        Show
        Keith Donald added a comment - Adding Juergen to watch list.
        Hide
        Juergen Hoeller added a comment -

        Indeed, Spring-generated scoped proxies are generally not serializable. I'm afraid this won't change before Spring 3.0, though, since it requires access from a deserialized object to its original containing BeanFactory... which isn't trivial to solve.

        Juergen

        Show
        Juergen Hoeller added a comment - Indeed, Spring-generated scoped proxies are generally not serializable. I'm afraid this won't change before Spring 3.0, though, since it requires access from a deserialized object to its original containing BeanFactory... which isn't trivial to solve. Juergen
        Hide
        Niels Frydenholm added a comment -

        Is there any news on this one? Will it be fixed in Spring 3.0 (and when will Spring 3.0 be released?).

        Links to a few posts having this problem:
        http://forum.springframework.org/showthread.php?t=60946
        http://forum.springframework.org/showthread.php?t=60905

        Show
        Niels Frydenholm added a comment - Is there any news on this one? Will it be fixed in Spring 3.0 (and when will Spring 3.0 be released?). Links to a few posts having this problem: http://forum.springframework.org/showthread.php?t=60946 http://forum.springframework.org/showthread.php?t=60905
        Hide
        Frantisek Rezac added a comment -

        What's the status of this bug? It should be marked as fixed or fixed version should be changed now when Spring 3 is out.

        Show
        Frantisek Rezac added a comment - What's the status of this bug? It should be marked as fixed or fixed version should be changed now when Spring 3 is out.
        Hide
        Taylor S. Wicksell added a comment -

        We'd also like an update, or at least a link to the relevant Spring Framework ticket that blocks this one.

        Show
        Taylor S. Wicksell added a comment - We'd also like an update, or at least a link to the relevant Spring Framework ticket that blocks this one.
        Hide
        Dario added a comment -

        I'm now trying with Spring 3.0.1, but it seems the problem is still present.
        Should I declare the property referencing the aop:scoped-proxy as transient?

        Show
        Dario added a comment - I'm now trying with Spring 3.0.1, but it seems the problem is still present. Should I declare the property referencing the aop:scoped-proxy as transient?
        Hide
        Jiri Stransky added a comment -

        I'd really like this to be fixed.

        Is there any workaround for having session scope beans serializable? I tried switching my @Scope annotation between ScopedProxyMode.INTERFACES and ScopedProxyMode.TARGET_CLASS, but it doesn't help.

        Show
        Jiri Stransky added a comment - I'd really like this to be fixed. Is there any workaround for having session scope beans serializable? I tried switching my @Scope annotation between ScopedProxyMode.INTERFACES and ScopedProxyMode.TARGET_CLASS, but it doesn't help.
        Hide
        Rossen Stoyanchev added a comment - - edited

        This is no longer an issue in the SWF 2.1.x branch, which is built on Spring 3. I tested as follows:

        1. Add Spring bean:
        <bean id="sessionBooking" class="org.springframework.webflow.samples.booking.Booking" scope="session">
        <aop:scoped-proxy proxy-target-class="true"/>
        <property name="beds" value="111"/>
        </bean>

        2. Declare flow variable:
        <var name="flowBooking" class="org.springframework.webflow.samples.booking.Booking"/>

        3. Add set action in on-start:
        <set name="flowBooking" value="sessionBooking"/>

        4. Print the following in the JSP (prints "111"):
        <spring:bind path="booking.hotel.price">$

        {status.value}

        </spring:bind>

        Show
        Rossen Stoyanchev added a comment - - edited This is no longer an issue in the SWF 2.1.x branch, which is built on Spring 3. I tested as follows: 1. Add Spring bean: <bean id="sessionBooking" class="org.springframework.webflow.samples.booking.Booking" scope="session"> <aop:scoped-proxy proxy-target-class="true"/> <property name="beds" value="111"/> </bean> 2. Declare flow variable: <var name="flowBooking" class="org.springframework.webflow.samples.booking.Booking"/> 3. Add set action in on-start: <set name="flowBooking" value="sessionBooking"/> 4. Print the following in the JSP (prints "111"): <spring:bind path="booking.hotel.price">$ {status.value} </spring:bind>

          People

          • Assignee:
            Rossen Stoyanchev
            Reporter:
            Roberto Ruiz
          • Votes:
            16 Vote for this issue
            Watchers:
            13 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development