Issue Details (XML | Word | Printable)

Key: SWF-1168
Type: Bug Bug
Status: Open Open
Priority: Critical Critical
Assignee: Keith Donald
Reporter: John Utting
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Spring Web Flow

Concurrent threads in flow causing sessionMap attribute to return null

Created: 20/Aug/09 03:52 AM   Updated: 03/Sep/09 03:54 AM
Component/s: Binding: Attribute Mapping System, Binding: Expression Language Support, Core: Flow Executor
Affects Version/s: 2.0.6, 2.0.8
Fix Version/s: None

Time Tracking:
Not Specified

Environment: Spring framework 2.5.6, Tomcat 5.5.27, OGNL 2.6.9, Webflow 2.0.6 and 2.0.8

Spring Forum Reference:: http://forum.springsource.org/showthread.php?p=255925#post255925


 Description  « Hide
Two concurrent threads executing the same flow action result in either externalContext.sessionMap.cart to return null or the returned value not being set in flowScope in one of the threads.

<on-start>
<set name="flowScope.cart" value="externalContext.sessionMap.cart" type="cart.ShoppingCart"/>
</on-start>

John Utting added a comment - 03/Sep/09 03:54 AM
Anyone explain this behaviour?

I decided to pass in the shopping cart to the top level flow using a flow handler which is fine in a single threaded environment.
flow:

<input name="cart" type="cart.ShoppingCart" required="true" value="flowScope.cart"/>
<action-state id="decideOnActivityType">
<evaluate expression="handsetActions.getActivityType(flowScope.cart.userSessionModel)"/>
<transition on="contractHandset" to="decideOnStartState"/>
<transition on="paygHandset" to="addPaygHandset"/>
</action-state>

flow handler method:
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request) {
        
        MutableAttributeMap map = null;
        
        HttpSession session = request.getSession();
        
        synchronized (session) {
         ShoppingCart cart = (ShoppingCart) session.getAttribute("cart");
         if(cart != null){
         map = new LocalAttributeMap();
         map.put("cart", cart);
         }
        }

        return map;
    }

Problems occur when two threads hit the flow at once and I get the following error:
ognl.OgnlException: source is null for getProperty(null, "userSessionModel")
at ognl.OgnlRuntime.getProperty(OgnlRuntime.java:1652)
at ognl.ASTProperty.getValueBody(ASTProperty.java:92)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.ASTChain.getValueBody(ASTChain.java:109)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.ASTMethod.getValueBody(ASTMethod.java:71)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.ASTChain.getValueBody(ASTChain.java:109)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at ognl.SimpleNode.getValue(SimpleNode.java:210)
at ognl.Ognl.getValue(Ognl.java:333)
at org.springframework.binding.expression.ognl.OgnlExpression.getValue(OgnlExpression.java:85)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Flow.start(Flow.java:535)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:364)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:222)
at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:193)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)

The error is complaining that flow.cart is null when trying to access userSessionModel, but how is this possible because the input mapping 'cart' is set as required and if it was null it would throw a FlowInputMappingException.