
|
If you were logged in you would be able to see more operations.
|
|
|
|
Two threads are loading flows from separate incoming web requests. Thread 1 is loading Flow A which has a Subflow B. Thread 2 is loading Flow B which has Subflow A. The FlowDefinitionRegistryImpl.getFlowDefinition(String id) method does this:
return getFlowDefinitionHolder(id).getFlowDefinition();
The FlowDefinitionHolder interface is implemented with RefreshableFlowDefinitionHolder (whose use is hardcoded in XmlFlowRegistrar). The RefreshableFlowDefinitionHolder.getFlowDefinition() method is synchronized. In this example, Thread 1 will own the monitor on Flow A's RefreshableFlowDefinitionHolder and Thread 2 will own the monitor on Flow B's RefreshableFlowDefinitionHolder . All subsequent requests to load either Flow A or Flow B will also wait behind this deadlock.
Here is a stack trace of a deadlock in SWF 1.0.3, but the same issue can be found in 1.0.5 with different line numbers:
org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:128)
org.springframework.webflow.engine.builder.DefaultFlowServiceLocator.getSubflow(DefaultFlowServiceLocator.java:79)
org.springframework.webflow.engine.builder.xml.LocalFlowServiceLocator.getSubflow(LocalFlowServiceLocator.java:120)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseSubflow(XmlFlowBuilder.java:684)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseAndAddSubflowState(XmlFlowBuilder.java:609)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseAndAddStateDefinitions(XmlFlowBuilder.java:570)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.buildStates(XmlFlowBuilder.java:354)
org.springframework.webflow.engine.builder.FlowAssembler.directAssembly(FlowAssembler.java:149)
org.springframework.webflow.engine.builder.FlowAssembler.assembleFlow(FlowAssembler.java:131)
org.springframework.webflow.engine.builder.RefreshableFlowDefinitionHolder.assembleFlow(RefreshableFlowDefinitionHolder.java:173)
org.springframework.webflow.engine.builder.RefreshableFlowDefinitionHolder.getFlowDefinition(RefreshableFlowDefinitionHolder.java:93)
org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:128)
org.springframework.webflow.executor.FlowExecutorImpl.launch(FlowExecutorImpl.java:204)
|
|
Description
|
Two threads are loading flows from separate incoming web requests. Thread 1 is loading Flow A which has a Subflow B. Thread 2 is loading Flow B which has Subflow A. The FlowDefinitionRegistryImpl.getFlowDefinition(String id) method does this:
return getFlowDefinitionHolder(id).getFlowDefinition();
The FlowDefinitionHolder interface is implemented with RefreshableFlowDefinitionHolder (whose use is hardcoded in XmlFlowRegistrar). The RefreshableFlowDefinitionHolder.getFlowDefinition() method is synchronized. In this example, Thread 1 will own the monitor on Flow A's RefreshableFlowDefinitionHolder and Thread 2 will own the monitor on Flow B's RefreshableFlowDefinitionHolder . All subsequent requests to load either Flow A or Flow B will also wait behind this deadlock.
Here is a stack trace of a deadlock in SWF 1.0.3, but the same issue can be found in 1.0.5 with different line numbers:
org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:128)
org.springframework.webflow.engine.builder.DefaultFlowServiceLocator.getSubflow(DefaultFlowServiceLocator.java:79)
org.springframework.webflow.engine.builder.xml.LocalFlowServiceLocator.getSubflow(LocalFlowServiceLocator.java:120)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseSubflow(XmlFlowBuilder.java:684)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseAndAddSubflowState(XmlFlowBuilder.java:609)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.parseAndAddStateDefinitions(XmlFlowBuilder.java:570)
org.springframework.webflow.engine.builder.xml.XmlFlowBuilder.buildStates(XmlFlowBuilder.java:354)
org.springframework.webflow.engine.builder.FlowAssembler.directAssembly(FlowAssembler.java:149)
org.springframework.webflow.engine.builder.FlowAssembler.assembleFlow(FlowAssembler.java:131)
org.springframework.webflow.engine.builder.RefreshableFlowDefinitionHolder.assembleFlow(RefreshableFlowDefinitionHolder.java:173)
org.springframework.webflow.engine.builder.RefreshableFlowDefinitionHolder.getFlowDefinition(RefreshableFlowDefinitionHolder.java:93)
org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:128)
org.springframework.webflow.executor.FlowExecutorImpl.launch(FlowExecutorImpl.java:204)
|
Show » |
Sort Order:
|