-
1. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Dec 20, 2012 1:22 AM (in response to r_delorimier)A potential cause of it is that subprocess has still active nodes so it does not complete and a cause of it could be an incorrect gateway type that you expect to be. When you look at the gateway that follows "submit for approval" it's parallel gateway which means both approve role and reject role tasks will be created. Next when you complete first task it goes directly to end node but since there is still active the other task sub process is not yet finished and it waits for the second task to be completed.
So most likely you would like to have exclusive gateway there and that should fix the problem. If not please post back and I'll try to find some time to look through the attached code.
HTH
-
2. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Dec 22, 2012 1:50 AM (in response to swiderski.maciej)I looked at all of the gateways, and other than the first divergent gateway, all the others were set to XOR. Here is the bpmn:
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
targetNamespace="http://www.jboss.org/drools"
typeLanguage="http://www.java.com/javaTypes"
expressionLanguage="http://www.mvel.org/2.0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
xmlns:g="http://www.jboss.org/drools/flow/gpd"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools">
<itemDefinition id="_2-ruleStateItem" structureRef="String" />
<process processType="Private" isExecutable="true" id="workflow" name="Rule Workflow Process" tns:packageName="defaultPackage" >
<laneSet>
<lane name="ruleState" >
</lane>
<lane name="ruleId" >
</lane>
</laneSet>
<!-- nodes -->
<startEvent id="_1" name="Start Process" />
<subProcess id="_2" name="Approval Process" >
<!-- variables -->
<property id="ruleState" itemSubjectRef="_2-ruleStateItem"/>
<!-- nodes -->
<startEvent id="_2-1" name="Start" />
<exclusiveGateway id="_2-2" name="Gateway" gatewayDirection="Converging" />
<userTask id="_2-3" name="Submit for Approval" >
<ioSpecification>
<dataInput id="_2-3_CommentInput" name="Comment" />
<dataInput id="_2-3_SkippableInput" name="Skippable" />
<dataInput id="_2-3_TaskNameInput" name="TaskName" />
<inputSet>
<dataInputRefs>_2-3_CommentInput</dataInputRefs>
<dataInputRefs>_2-3_SkippableInput</dataInputRefs>
<dataInputRefs>_2-3_TaskNameInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<targetRef>_2-3_CommentInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Task to submit the draft rule</from>
<to xsi:type="tFormalExpression">_2-3_CommentInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-3_SkippableInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">true</from>
<to xsi:type="tFormalExpression">_2-3_SkippableInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-3_TaskNameInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Submit for Approval</from>
<to xsi:type="tFormalExpression">_2-3_TaskNameInput</to>
</assignment>
</dataInputAssociation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>submitter</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<parallelGateway id="_2-4" name="Gateway" gatewayDirection="Diverging" />
<userTask id="_2-5" name="Approve Rule" >
<extensionElements>
<tns:onExit-script scriptFormat="http://www.java.com/java">
<script>org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
process.setVariable("ruleState", "LIVE");</script>
</tns:onExit-script>
</extensionElements>
<ioSpecification>
<dataInput id="_2-5_CommentInput" name="Comment" />
<dataInput id="_2-5_SkippableInput" name="Skippable" />
<dataInput id="_2-5_TaskNameInput" name="TaskName" />
<inputSet>
<dataInputRefs>_2-5_CommentInput</dataInputRefs>
<dataInputRefs>_2-5_SkippableInput</dataInputRefs>
<dataInputRefs>_2-5_TaskNameInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<targetRef>_2-5_CommentInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Approve the rule</from>
<to xsi:type="tFormalExpression">_2-5_CommentInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-5_SkippableInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">true</from>
<to xsi:type="tFormalExpression">_2-5_SkippableInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-5_TaskNameInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Approve Rule</from>
<to xsi:type="tFormalExpression">_2-5_TaskNameInput</to>
</assignment>
</dataInputAssociation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>approver</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>appUser</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<userTask id="_2-6" name="Reject Rule" >
<extensionElements>
<tns:onExit-script>
<script>org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
process.setVariable("ruleState", "DRAFT");</script>
</tns:onExit-script>
</extensionElements>
<ioSpecification>
<dataInput id="_2-6_CommentInput" name="Comment" />
<dataInput id="_2-6_SkippableInput" name="Skippable" />
<dataInput id="_2-6_TaskNameInput" name="TaskName" />
<inputSet>
<dataInputRefs>_2-6_CommentInput</dataInputRefs>
<dataInputRefs>_2-6_SkippableInput</dataInputRefs>
<dataInputRefs>_2-6_TaskNameInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<targetRef>_2-6_CommentInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Reject the rule</from>
<to xsi:type="tFormalExpression">_2-6_CommentInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-6_SkippableInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">true</from>
<to xsi:type="tFormalExpression">_2-6_SkippableInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_2-6_TaskNameInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Reject Rule</from>
<to xsi:type="tFormalExpression">_2-6_TaskNameInput</to>
</assignment>
</dataInputAssociation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>approver</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>appUser</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<exclusiveGateway id="_2-7" name="Gateway" gatewayDirection="Converging" />
<exclusiveGateway id="_2-8" name="approveDecision" gatewayDirection="Diverging" />
<endEvent id="_2-9" name="FinishSubProcess" />
<!-- connections -->
<sequenceFlow id="_2-1-_2-2" sourceRef="_2-1" targetRef="_2-2" />
<sequenceFlow id="_2-8-_2-2" sourceRef="_2-8" targetRef="_2-2" name="Rejected" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression" >org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
if (((String)process.getVariable("ruleState")).equals("DRAFT"))
{
System.out.println("Rule rejected and staying DRAFT. Back to the beginning");
return true;
}
else
{
return false;
}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_2-2-_2-3" sourceRef="_2-2" targetRef="_2-3" />
<sequenceFlow id="_2-3-_2-4" sourceRef="_2-3" targetRef="_2-4" />
<sequenceFlow id="_2-4-_2-5" sourceRef="_2-4" targetRef="_2-5" />
<sequenceFlow id="_2-4-_2-6" sourceRef="_2-4" targetRef="_2-6" />
<sequenceFlow id="_2-6-_2-7" sourceRef="_2-6" targetRef="_2-7" />
<sequenceFlow id="_2-5-_2-7" sourceRef="_2-5" targetRef="_2-7" />
<sequenceFlow id="_2-7-_2-8" sourceRef="_2-7" targetRef="_2-8" />
<sequenceFlow id="_2-8-_2-9" sourceRef="_2-8" targetRef="_2-9" name="Go live" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression" >org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
if (((String)process.getVariable("ruleState")).equals("LIVE"))
{
System.out.println("Rule approved and going LIVE");
return true;
}
else
{
return false;
}</conditionExpression>
</sequenceFlow>
</subProcess>
<userTask id="_3" name="Modify Rule" >
<extensionElements>
<tns:onExit-script scriptFormat="http://www.java.com/java">
<script>org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
process.setVariable("ruleState", "DRAFT");</script>
</tns:onExit-script>
</extensionElements>
<ioSpecification>
<dataInput id="_3_CommentInput" name="Comment" />
<dataInput id="_3_SkippableInput" name="Skippable" />
<dataInput id="_3_TaskNameInput" name="TaskName" />
<inputSet>
<dataInputRefs>_3_CommentInput</dataInputRefs>
<dataInputRefs>_3_SkippableInput</dataInputRefs>
<dataInputRefs>_3_TaskNameInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<targetRef>_3_CommentInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Modify the rule</from>
<to xsi:type="tFormalExpression">_3_CommentInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_3_SkippableInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">true</from>
<to xsi:type="tFormalExpression">_3_SkippableInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_3_TaskNameInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Modify Rule</from>
<to xsi:type="tFormalExpression">_3_TaskNameInput</to>
</assignment>
</dataInputAssociation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>submitter</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>editor</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<endEvent id="_4" name="End" >
<terminateEventDefinition/>
</endEvent>
<exclusiveGateway id="_5" name="Gateway" gatewayDirection="Converging" />
<parallelGateway id="_6" name="Gateway" gatewayDirection="Diverging" />
<exclusiveGateway id="_7" name="Gateway" gatewayDirection="Converging" />
<exclusiveGateway id="_8" name="Gateway" gatewayDirection="Diverging" />
<userTask id="_9" name="Start Workflow" >
<extensionElements>
<tns:onExit-script scriptFormat="http://www.java.com/java">
<script>System.out.println("Start Workflow triggered");</script>
</tns:onExit-script>
</extensionElements>
<ioSpecification>
<dataInput id="_9_CommentInput" name="Comment" />
<dataInput id="_9_SkippableInput" name="Skippable" />
<dataInput id="_9_TaskNameInput" name="TaskName" />
<dataInput id="_9_GroupIdInput" name="GroupId" />
<inputSet>
<dataInputRefs>_9_CommentInput</dataInputRefs>
<dataInputRefs>_9_SkippableInput</dataInputRefs>
<dataInputRefs>_9_TaskNameInput</dataInputRefs>
<dataInputRefs>_9_GroupIdInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<targetRef>_9_CommentInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Starts the workflow</from>
<to xsi:type="tFormalExpression">_9_CommentInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_9_SkippableInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">false</from>
<to xsi:type="tFormalExpression">_9_SkippableInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_9_TaskNameInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression">Start Workflow</from>
<to xsi:type="tFormalExpression">_9_TaskNameInput</to>
</assignment>
</dataInputAssociation>
<dataInputAssociation>
<targetRef>_9_GroupIdInput</targetRef>
<assignment>
<from xsi:type="tFormalExpression"></from>
<to xsi:type="tFormalExpression">_9_GroupIdInput</to>
</assignment>
</dataInputAssociation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>appUser</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<!-- connections -->
<sequenceFlow id="_6-_2" sourceRef="_6" targetRef="_2" />
<sequenceFlow id="_6-_3" sourceRef="_6" targetRef="_3" />
<sequenceFlow id="_8-_4" sourceRef="_8" targetRef="_4" name="Finish workflow" >
<conditionExpression xsi:type="tFormalExpression" >org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
System.out.println("Rule state is now " + ((String)process.getVariable("ruleState")));
if (((String)process.getVariable("ruleState")).equals("LIVE"))
{
System.out.println("Finish workflow");
return true;
}
else
{
return false;
}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_3-_5" sourceRef="_3" targetRef="_5" />
<sequenceFlow id="_2-_5" sourceRef="_2" targetRef="_5" />
<sequenceFlow id="_7-_6" sourceRef="_7" targetRef="_6" />
<sequenceFlow id="_8-_7" sourceRef="_8" targetRef="_7" name="Return to start" >
<conditionExpression xsi:type="tFormalExpression" >org.drools.runtime.process.WorkflowProcessInstance process = (org.drools.runtime.process.WorkflowProcessInstance)kcontext.getProcessInstance();
System.out.println("Rule state is now " + ((String)process.getVariable("ruleState")));
if (((String)process.getVariable("ruleState")).equals("DRAFT"))
{
System.out.println("Go back to start");
return true;
}
else
{
return false;
}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_9-_7" sourceRef="_9" targetRef="_7" />
<sequenceFlow id="_5-_8" sourceRef="_5" targetRef="_8" />
<sequenceFlow id="_1-_9" sourceRef="_1" targetRef="_9" />
</process>
<bpmndi:BPMNDiagram>
<bpmndi:BPMNPlane bpmnElement="workflow" >
<bpmndi:BPMNShape bpmnElement="_1" >
<dc:Bounds x="236" y="12" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2" >
<dc:Bounds x="360" y="191" width="607" height="502" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-1" >
<dc:Bounds x="456" y="220" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-2" >
<dc:Bounds x="458" y="315" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-3" >
<dc:Bounds x="406" y="400" width="153" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-4" >
<dc:Bounds x="458" y="488" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-5" >
<dc:Bounds x="435" y="609" width="100" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-6" >
<dc:Bounds x="573" y="490" width="100" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-7" >
<dc:Bounds x="737" y="611" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-8" >
<dc:Bounds x="732" y="319" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2-9" >
<dc:Bounds x="895" y="318" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_3" >
<dc:Bounds x="90" y="326" width="100" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_4" >
<dc:Bounds x="40" y="726" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_5" >
<dc:Bounds x="118" y="640" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_6" >
<dc:Bounds x="236" y="181" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_7" >
<dc:Bounds x="41" y="187" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_8" >
<dc:Bounds x="40" y="640" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_9" >
<dc:Bounds x="210" y="102" width="100" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_2-1-_2-2" >
<di:waypoint x="120" y="53" />
<di:waypoint x="122" y="148" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-8-_2-2" >
<di:waypoint x="396" y="152" />
<di:waypoint x="122" y="148" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-2-_2-3" >
<di:waypoint x="122" y="148" />
<di:waypoint x="122" y="233" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-3-_2-4" >
<di:waypoint x="122" y="233" />
<di:waypoint x="122" y="321" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-4-_2-5" >
<di:waypoint x="122" y="321" />
<di:waypoint x="125" y="442" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-4-_2-6" >
<di:waypoint x="122" y="321" />
<di:waypoint x="263" y="323" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-6-_2-7" >
<di:waypoint x="263" y="323" />
<di:waypoint x="401" y="444" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-5-_2-7" >
<di:waypoint x="125" y="442" />
<di:waypoint x="401" y="444" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-7-_2-8" >
<di:waypoint x="401" y="444" />
<di:waypoint x="396" y="152" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-8-_2-9" >
<di:waypoint x="396" y="152" />
<di:waypoint x="559" y="151" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_6-_2" >
<di:waypoint x="260" y="205" />
<di:waypoint x="663" y="442" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_6-_3" >
<di:waypoint x="260" y="205" />
<di:waypoint x="140" y="350" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8-_4" >
<di:waypoint x="64" y="664" />
<di:waypoint x="64" y="750" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_3-_5" >
<di:waypoint x="140" y="350" />
<di:waypoint x="142" y="664" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-_5" >
<di:waypoint x="663" y="442" />
<di:waypoint x="142" y="664" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_7-_6" >
<di:waypoint x="65" y="211" />
<di:waypoint x="260" y="205" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8-_7" >
<di:waypoint x="64" y="664" />
<di:waypoint x="65" y="211" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9-_7" >
<di:waypoint x="260" y="126" />
<di:waypoint x="65" y="211" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_5-_8" >
<di:waypoint x="142" y="664" />
<di:waypoint x="64" y="664" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_1-_9" >
<di:waypoint x="260" y="36" />
<di:waypoint x="260" y="126" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
-
3. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Dec 22, 2012 1:37 PM (in response to r_delorimier)I misspoke. There are two divergent AND gateways; one before the modify task and embedded subprocess, and one in the subprocess before the reject and accept tasks.
-
4. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Dec 27, 2012 12:59 PM (in response to r_delorimier)yes, and in fact the problem is with parallel gateway that splits the flow into both Approve and Reject user tasks which I believe is not what you want. So changing that to XOR gateway should make the subprocess complete as expected.
HTH
-
5. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Dec 30, 2012 1:58 AM (in response to swiderski.maciej)Ok, so I do not understand how the workflow works then. What I think you are saying is that I really need to have a single human task that combines the reject and accept decisions. Then the divergent gateway is used to direct the workflow to the end or go back to the beginning, using a flag as an indicator of which way to go.
That is a little less satisfactory. I wanted to pick up the two unexecuted tasks (accept and reject), and present them as buttons. If one was executed, then jbpm would remove the other one. I thought you could use a divergent parallel gateway with multiple skippable tasks, and an XOR convergent gateway on the other side. The first human task completed would go to the convergent gateway and complete the flow for that area between the divergent and convergent gateways. The branches that did not complete were then deleted or invalidated. Are you saying this is not possible?
-
6. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Jan 3, 2013 5:39 AM (in response to r_delorimier)what id does is when reaching parallel gateway it will create both tasks - in your case they represent buttons so you would need to do one of the following:
- complete the task that represents button that was used and skip the other
- make the end event a terminate so as soon as the first enters that end event it will cancel all other active nodes in the sub process
the usual case is that you have single task that is to either approve or reject and then reason over the out come of a task. I think this more refers to the real usage as user will see only single task. In the process attached you have two tasks so using regular task list user would see both of them.
HTH
-
7. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Jan 12, 2013 4:37 PM (in response to swiderski.maciej)What you are describing is different from what I am seeing. You can follow the path I am taking in the workflow I appended above to see how the tasks are related. In my test I am doing this set of tasks and seeing which tasks are still reserved afterwards. The ones I am marking bold should not still be there:
- Start Workflow
- Submit for Approval
- Modify Rule
- Submit for Approval
- Modify Rule
- Approve Rule
- Reject Rule
- Reject Rule
- Modify Rule
- Submit Rule
- Submit for Approval
- Modify Rule
- Approve Rule - orphan
- Reject Rule
- Approve Rule
- Modify Rule
- Approve Rule - orphan
- Reject Rule - orphan
- Approve Rule - orphan
- Submit for Approval
- Modify Rule
- Submit for Approval
- Approve Rule - orphan
- Reject Rule - orphan
- Approve Rule - orphan
- Modify Rule
- Approve Rule
- Reject Rule
- Approve Rule
- Reject Rule - orphan
- Approve Rule - orphan
- Modify Rule - orphan
- Approve Rule - orphan
- Reject Rule - orphan
When I check to see if the process instance is complete, it is not. You had mentioned that all tasks need to be complete or otherwise not active, so I am guessing this is why the process instance is still active. Even when I set the end node in the subprocess to terminate and fire it, the remaining tasks in the subprocess are still reserved.
Because I have duplicate human tasks, now I need to make sure that I retrieve the latest human task using the highest task id, so I do not get an orphaned one by mistake. I do not know what will happen if I execute an orphaned task instead of the latest one, but it could very well be unpredictable.
If I need to, I can log which nodes have been fired and then check if the end node in the subprocess has been fired, and use that to treat the workflow as complete. However, that is not optimal. I would have expected that the xor convergent node and the subprocess would both do cleanup of uncompleted tasks.
- Start Workflow
-
8. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Jan 14, 2013 7:06 PM (in response to r_delorimier)Is there anything I am not doing correct to accumulate these orphaned tasks?
For anyone who stumbles upon this thread, I am using this query to see which tasks are still open for a process instance:
select task0_.id as col_0_0_, task0_.processInstanceId as col_1_0_, names5_.text as col_2_0_,
subjects3_.text as col_3_0_, descriptio4_.text as col_4_0_, task0_.status as col_5_0_,
task0_.priority as col_6_0_, task0_.skipable as col_7_0_, user2_.id as col_8_0_,
user1_.id as col_9_0_, task0_.createdOn as col_10_0_, task0_.activationTime as col_11_0_,
task0_.expirationTime as col_12_0_, task0_.processId as col_13_0_,
task0_.processSessionId as col_14_0_
from Task task0_
left outer join OrganizationalEntity user1_ on task0_.createdBy_id=user1_.id
left outer join OrganizationalEntity user2_ on task0_.actualOwner_id=user2_.id
left outer join I18NText subjects3_ on task0_.id=subjects3_.Task_Subjects_Id
left outer join I18NText descriptio4_ on task0_.id=descriptio4_.Task_Descriptions_Id
left outer join I18NText names5_ on task0_.id=names5_.Task_Names_Id, OrganizationalEntity organizati6_
where task0_.archived=0
--and (organizati6_.id='approver' or organizati6_.id in ('admin', 'manager', 'user'))
and (organizati6_.id in
(
select potentialo7_.entity_id
from PeopleAssignments_PotOwners potentialo7_
where task0_.id=potentialo7_.task_id
)
)
and
(
names5_.language='en-UK'
or
(
select count(names8_.Task_Names_Id)
from I18NText names8_
where task0_.id=names8_.Task_Names_Id
)
=0
)
and
(
subjects3_.language='en-UK'
or
(
select count(subjects9_.Task_Subjects_Id)
from I18NText subjects9_
where task0_.id=subjects9_.Task_Subjects_Id
)
=0
)
and
(
descriptio4_.language='en-UK'
or
(
select count(descriptio10_.Task_Descriptions_Id)
from I18NText descriptio10_
where task0_.id=descriptio10_.Task_Descriptions_Id
)
=0
)
--and (task0_.status in ('Created' , 'Ready' , 'Reserved' , 'InProgress' , 'Suspended'))
--and (task0_.status not in ('Completed'))
and (task0_.expirationTime is null)
and task0_.processInstanceId=292
;
select * from workiteminfo
where processinstanceid = 234;
You would need to find the process instance id to see what you have, and replace 234 with it. A am using a debugger in eclipse so I can see what is there after each human task is executed,
-
9. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Jan 15, 2013 7:31 AM (in response to r_delorimier)Robert, please find attached zip with two files:
- modified process definition
- adjusted test case
in general what I changed in there is the gateway in subprocess after approve reject user tasks to be parallel gateway, so it will wait until both tasks are finished. Finished does not have to mean completed as you can notice in the adjusted test case, it skips the task that was not selected.
HTH
-
Archive.zip 5.3 KB
-
-
10. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Jan 16, 2013 10:22 AM (in response to swiderski.maciej)Hi Maciej,
Thanks for the example. I see that you have added steps to skip the human tasks that will not be used, so we can now pass the AND convergent gateway instead of using the XOR version. You have also answered my question. Any cleanup we need to do is on the client, the JPBM framework itself will not invalidate (skip) items using the XOR gateway or exiting out of a subprocess. I will put in a feature request for that cleanup, as I cannot think of a reason why you would want the tasks that did not make it to the XOR gateway to remain in reserved state.
thanks again,
Rob
-
11. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Jan 16, 2013 12:35 PM (in response to r_delorimier)Robert, it is because XOR (according to bpmn2 spec) does allow to be visited more than one time, what it does in converging mode is that it will not synchronize the tokens on it but move the flow as soon as the first token reaches it. It is possible and completely valid that at some point later another token will go through the xor converging gateway again and thus it does not cancel (skip) it.
Although I think that subprocess should be capable of canceling active nodes when it is terminating. Will check that soon and post back the result. If I would not do it within a week please ping me here
Cheers
-
12. Re: JBPM 5: Workflow not leaving embedded sub process
r_delorimier Jan 16, 2013 1:01 PM (in response to swiderski.maciej)Maciej,
Thank you for the insight. I had not thought about the case where tasks could be fired after the xor gateway has finished. But in cases where the flow returns back to the same XOR node, would there not be duplicate tasks again? Since I have not worked on that type of scenario, it is a bit blurry to me.
Thanx!
-
13. Re: JBPM 5: Workflow not leaving embedded sub process
swiderski.maciej Jan 16, 2013 2:03 PM (in response to r_delorimier)you're right, there will be duplicated tasks which in some cases this is expected behavior.