13 Replies Latest reply on Jan 16, 2013 2:03 PM by swiderski.maciej

    JBPM 5: Workflow not leaving embedded sub process

    r_delorimier

      Hi all,

       

      I am trying to create a workflow with human tasks, convergent and divergent gateways, and an embedded subprocess. For some reason it looks like the workflow does not continue after the subprocess finishes to go to the final end point. See the workflow image:

       

      workflow.png

      I am using a variable in the constraints of the divergent gateway to decide which direction the workflow will go. After I select the "Appove Rule" node, the next nodes are a convergent and divergent gateway. I can see that it is making it to the the divergent gateway, as I added in some code the the constraint that goes to the termination node in the subprocess:

       

      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;

      }

       

      I can see the Text "Rule approved and going LIVE" in the console when running my code, so it should be going to the terninal node. Outside of the subprocess is another convergent and divergent node. The divergent node uses the ruleState variable to decide whether go back through the process again or go to the terminal node, and again to am printing out what the decision is. I do not see any of this text when I run the code. I also assert that the End node was triggered and the process instance is completed, and both of these fail. I am including the workflow and code as a maven project so you can run the test with "mvn install" and take a look at it yourself.

        • 1. Re: JBPM 5: Workflow not leaving embedded sub process
          swiderski.maciej

          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

            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

              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

                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

                  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

                    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

                      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:

                       

                      1. Start Workflow
                        1. Submit for Approval
                        2. Modify Rule
                      2. Submit for Approval
                        1. Modify Rule
                        2. Approve Rule
                        3. Reject Rule
                      3. Reject Rule
                        1. Modify Rule
                        2. Submit Rule
                      4. Submit for Approval
                        1. Modify Rule
                        2. Approve Rule - orphan
                        3. Reject Rule
                        4. Approve Rule
                      5. Modify Rule
                        1. Approve Rule - orphan
                        2. Reject Rule - orphan
                        3. Approve Rule - orphan
                        4. Submit for Approval
                        5. Modify Rule
                      6. Submit for Approval
                        1. Approve Rule - orphan
                        2. Reject Rule - orphan
                        3. Approve Rule - orphan
                        4. Modify Rule
                        5. Approve Rule
                        6. Reject Rule
                      7. Approve Rule
                        1. Reject Rule - orphan
                        2. Approve Rule - orphan
                        3. Modify Rule - orphan
                        4. Approve Rule - orphan
                        5. 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.

                      • 8. Re: JBPM 5: Workflow not leaving embedded sub process
                        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

                          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

                          • 10. Re: JBPM 5: Workflow not leaving embedded sub process
                            r_delorimier

                            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

                              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

                                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

                                  you're right, there will be duplicated tasks which in some cases this is expected behavior.