Jozef Chocholáček
2013-03-04 09:45:05 UTC
Jozef ChocholáÄek [https://community.jboss.org/people/jchocholacek] created the discussion
"Output mapping from Human Task does not work"
To view the discussion, visit: https://community.jboss.org/message/800540#800540
--------------------------------------------------------------
Hello there,
I have a problem with mapping the Human Task output to process variables. My code is inspired by the https://community.jboss.org/people/bpmn2user/blog/2011/09/21/jbpm5-web-example https://community.jboss.org/people/bpmn2user/blog/2011/09/21/jbpm5-web-example blog post.
I run it in Tomcat 6, using the Mina HT service.
Here is my process definition:
<?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="_mgnlDataItem" structureRef="java.util.Map" />
 <itemDefinition id="_9-mgnlDataItem" structureRef="java.util.Map" />
 <process processType="Private" isExecutable="true" id="jch.workflow.test" name="Flow Test" tns:packageName="defaultPackage" >
   <extensionElements>
    <tns:import name="java.util.Map" />
   </extensionElements>
   <!-- process variables -->
   <property id="mgnlData" itemSubjectRef="_mgnlDataItem"/>
   <!-- nodes -->
   <startEvent id="_1" name="StartProcess" />
   <endEvent id="_6" name="End" >
       <terminateEventDefinition/>
   </endEvent>
   <scriptTask id="_7" name="Entry Script" scriptFormat="http://www.java.com/java" >
     <script>String processId = "" + kcontext.getProcessInstance().getId();
System.out.println("ENTRY SCRIPT: " + processId);
Map data = (Map) kcontext.getVariable("mgnlData");
if (data==null) {
 System.out.println("Empty DATA");
} else {
 System.out.println("DATA: " + data.toString());
}
</script>
   </scriptTask>
   <scriptTask id="_8" name="Exit Script" scriptFormat="http://www.java.com/java" >
     <script>String processId = "" + kcontext.getProcessInstance().getId();
System.out.println("EXIT SCRIPT: " + processId);
Map data = (Map) kcontext.getVariable("mgnlData");
if (data==null) {
 System.out.println("Empty DATA");
} else {
 System.out.println("DATA: " + data.toString());
}
</script>
   </scriptTask>
   <userTask id="_9" name="User Task" >
     <extensionElements>
       <tns:onEntry-script scriptFormat="http://www.java.com/java">
         <script>System.out.println("Human Task - Entry action");</script>
       </tns:onEntry-script>
       <tns:onExit-script scriptFormat="http://www.java.com/java">
         <script>System.out.println("Human Task - Exit action");</script>
       </tns:onExit-script>
     </extensionElements>
     <ioSpecification>
       <dataInput id="_9_ContentInput" name="Content" />
       <dataOutput id="_9_mgnlDataOutput" name="mgnlData" />
       <inputSet>
         <dataInputRefs>_9_ContentInput</dataInputRefs>
       </inputSet>
       <outputSet>
         <dataOutputRefs>_9_mgnlDataOutput</dataOutputRefs>
       </outputSet>
     </ioSpecification>
     <dataInputAssociation>
       <sourceRef>mgnlData</sourceRef>
       <targetRef>_9_ContentInput</targetRef>
     </dataInputAssociation>
     <dataOutputAssociation>
       <sourceRef>_9_mgnlDataOutput</sourceRef>
       <targetRef>mgnlData</targetRef>
     </dataOutputAssociation>
     <potentialOwner>
       <resourceAssignmentExpression>
         <formalExpression>peter</formalExpression>
       </resourceAssignmentExpression>
     </potentialOwner>
   </userTask>
   <!-- connections -->
   <sequenceFlow id="_8-_6" sourceRef="_8" targetRef="_6" />
   <sequenceFlow id="_1-_7" sourceRef="_1" targetRef="_7" />
   <sequenceFlow id="_9-_8" sourceRef="_9" targetRef="_8" />
   <sequenceFlow id="_7-_9" sourceRef="_7" targetRef="_9" />
 </process>
 <bpmndi:BPMNDiagram>
   ...
 </bpmndi:BPMNDiagram>
</definitions>
This is how I start the process:
   public RunningProcess launch(Workflow workflow, Map<String, Object> parameters) throws WorkflowException {
       Map<String,Object> processParams = new HashMap<String,Object>();
       processParams.put(RunningProcess.DATA, parameters);
       try {
           // start user transaction
           UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
           ut.begin();
           // start process
           ProcessInstance pi = this.ksession.startProcess(workflow.getId(), processParams);
           this.ksession.fireAllRules();
           // commit
           ut.commit();
           return new ProcessImpl(pi);
       } catch (Exception e) {
           log.debug("Error starting workflow [" + workflow.getId() + "].", e);
           throw new WorkflowException("Error starting workflow.", e);
       }
   }
RunningProcess.DATA containg the "mgnlData" string, Workflow is my bean holding the process definition data, RunningProcess / ProcessImpl are my wrappers for the ProcessInstace. Then I call this method from:
Map<String, Object> data = new HashMap<String, Object>();
data.put("string", "string value");
data.put("int", 42);
process = manager.launch("test", data);
And how I handle the Human Task:
// prepare data
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> mgnlData = new HashMap<String, Object>();
mgnlData.put("int", 1111);
mgnlData.put("string", "new value");
data.put(RunningProcess.DATA, mgnlData);
// start user transaction
UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
ut.begin();
// start processing the task
BlockingTaskOperationResponseHandler responseHandler = new BlockingTaskOperationResponseHandler();
this.taskClient.start(summary.getId(), user, responseHandler);
responseHandler.waitTillDone(1000);
// and complete the task
responseHandler = new BlockingTaskOperationResponseHandler();
this.taskClient.complete(summary.getId(), user, map2contentData(data), responseHandler);
responseHandler.waitTillDone(2000);
// commit transaction
ut.commit();
The map2contentData method is based on the code from jBPM5 web example blog post:
   protected ContentData map2contentData(Map data) {
       ContentData contentData = null;
       if (data != null) {
           ByteArrayOutputStream bos = new ByteArrayOutputStream();
           ObjectOutputStream out;
           try {
               out = new ObjectOutputStream(bos);
               out.writeObject(data);
               out.close();
               contentData = new ContentData();
               contentData.setContent(bos.toByteArray());
               contentData.setAccessType(AccessType.Inline);
           } catch (IOException e) {
               log.error("Problem saving output data.", e);
           }
       }
       return contentData;
   }
But it results in the empty process variable in the end (console output):
ENTRY SCRIPT: 425984
DATA: {int=42, string=string value}
Human Task - Entry action
...
Human Task - Exit action
EXIT SCRIPT: 425984
Empty DATA
I expect sort-of PEBKAC error, but I couldn't find what did I forget...
--------------------------------------------------------------
Reply to this message by going to Community
[https://community.jboss.org/message/800540#800540]
Start a new discussion in jBPM at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]
"Output mapping from Human Task does not work"
To view the discussion, visit: https://community.jboss.org/message/800540#800540
--------------------------------------------------------------
Hello there,
I have a problem with mapping the Human Task output to process variables. My code is inspired by the https://community.jboss.org/people/bpmn2user/blog/2011/09/21/jbpm5-web-example https://community.jboss.org/people/bpmn2user/blog/2011/09/21/jbpm5-web-example blog post.
I run it in Tomcat 6, using the Mina HT service.
Here is my process definition:
<?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="_mgnlDataItem" structureRef="java.util.Map" />
 <itemDefinition id="_9-mgnlDataItem" structureRef="java.util.Map" />
 <process processType="Private" isExecutable="true" id="jch.workflow.test" name="Flow Test" tns:packageName="defaultPackage" >
   <extensionElements>
    <tns:import name="java.util.Map" />
   </extensionElements>
   <!-- process variables -->
   <property id="mgnlData" itemSubjectRef="_mgnlDataItem"/>
   <!-- nodes -->
   <startEvent id="_1" name="StartProcess" />
   <endEvent id="_6" name="End" >
       <terminateEventDefinition/>
   </endEvent>
   <scriptTask id="_7" name="Entry Script" scriptFormat="http://www.java.com/java" >
     <script>String processId = "" + kcontext.getProcessInstance().getId();
System.out.println("ENTRY SCRIPT: " + processId);
Map data = (Map) kcontext.getVariable("mgnlData");
if (data==null) {
 System.out.println("Empty DATA");
} else {
 System.out.println("DATA: " + data.toString());
}
</script>
   </scriptTask>
   <scriptTask id="_8" name="Exit Script" scriptFormat="http://www.java.com/java" >
     <script>String processId = "" + kcontext.getProcessInstance().getId();
System.out.println("EXIT SCRIPT: " + processId);
Map data = (Map) kcontext.getVariable("mgnlData");
if (data==null) {
 System.out.println("Empty DATA");
} else {
 System.out.println("DATA: " + data.toString());
}
</script>
   </scriptTask>
   <userTask id="_9" name="User Task" >
     <extensionElements>
       <tns:onEntry-script scriptFormat="http://www.java.com/java">
         <script>System.out.println("Human Task - Entry action");</script>
       </tns:onEntry-script>
       <tns:onExit-script scriptFormat="http://www.java.com/java">
         <script>System.out.println("Human Task - Exit action");</script>
       </tns:onExit-script>
     </extensionElements>
     <ioSpecification>
       <dataInput id="_9_ContentInput" name="Content" />
       <dataOutput id="_9_mgnlDataOutput" name="mgnlData" />
       <inputSet>
         <dataInputRefs>_9_ContentInput</dataInputRefs>
       </inputSet>
       <outputSet>
         <dataOutputRefs>_9_mgnlDataOutput</dataOutputRefs>
       </outputSet>
     </ioSpecification>
     <dataInputAssociation>
       <sourceRef>mgnlData</sourceRef>
       <targetRef>_9_ContentInput</targetRef>
     </dataInputAssociation>
     <dataOutputAssociation>
       <sourceRef>_9_mgnlDataOutput</sourceRef>
       <targetRef>mgnlData</targetRef>
     </dataOutputAssociation>
     <potentialOwner>
       <resourceAssignmentExpression>
         <formalExpression>peter</formalExpression>
       </resourceAssignmentExpression>
     </potentialOwner>
   </userTask>
   <!-- connections -->
   <sequenceFlow id="_8-_6" sourceRef="_8" targetRef="_6" />
   <sequenceFlow id="_1-_7" sourceRef="_1" targetRef="_7" />
   <sequenceFlow id="_9-_8" sourceRef="_9" targetRef="_8" />
   <sequenceFlow id="_7-_9" sourceRef="_7" targetRef="_9" />
 </process>
 <bpmndi:BPMNDiagram>
   ...
 </bpmndi:BPMNDiagram>
</definitions>
This is how I start the process:
   public RunningProcess launch(Workflow workflow, Map<String, Object> parameters) throws WorkflowException {
       Map<String,Object> processParams = new HashMap<String,Object>();
       processParams.put(RunningProcess.DATA, parameters);
       try {
           // start user transaction
           UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
           ut.begin();
           // start process
           ProcessInstance pi = this.ksession.startProcess(workflow.getId(), processParams);
           this.ksession.fireAllRules();
           // commit
           ut.commit();
           return new ProcessImpl(pi);
       } catch (Exception e) {
           log.debug("Error starting workflow [" + workflow.getId() + "].", e);
           throw new WorkflowException("Error starting workflow.", e);
       }
   }
RunningProcess.DATA containg the "mgnlData" string, Workflow is my bean holding the process definition data, RunningProcess / ProcessImpl are my wrappers for the ProcessInstace. Then I call this method from:
Map<String, Object> data = new HashMap<String, Object>();
data.put("string", "string value");
data.put("int", 42);
process = manager.launch("test", data);
And how I handle the Human Task:
// prepare data
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> mgnlData = new HashMap<String, Object>();
mgnlData.put("int", 1111);
mgnlData.put("string", "new value");
data.put(RunningProcess.DATA, mgnlData);
// start user transaction
UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
ut.begin();
// start processing the task
BlockingTaskOperationResponseHandler responseHandler = new BlockingTaskOperationResponseHandler();
this.taskClient.start(summary.getId(), user, responseHandler);
responseHandler.waitTillDone(1000);
// and complete the task
responseHandler = new BlockingTaskOperationResponseHandler();
this.taskClient.complete(summary.getId(), user, map2contentData(data), responseHandler);
responseHandler.waitTillDone(2000);
// commit transaction
ut.commit();
The map2contentData method is based on the code from jBPM5 web example blog post:
   protected ContentData map2contentData(Map data) {
       ContentData contentData = null;
       if (data != null) {
           ByteArrayOutputStream bos = new ByteArrayOutputStream();
           ObjectOutputStream out;
           try {
               out = new ObjectOutputStream(bos);
               out.writeObject(data);
               out.close();
               contentData = new ContentData();
               contentData.setContent(bos.toByteArray());
               contentData.setAccessType(AccessType.Inline);
           } catch (IOException e) {
               log.error("Problem saving output data.", e);
           }
       }
       return contentData;
   }
But it results in the empty process variable in the end (console output):
ENTRY SCRIPT: 425984
DATA: {int=42, string=string value}
Human Task - Entry action
...
Human Task - Exit action
EXIT SCRIPT: 425984
Empty DATA
I expect sort-of PEBKAC error, but I couldn't find what did I forget...
--------------------------------------------------------------
Reply to this message by going to Community
[https://community.jboss.org/message/800540#800540]
Start a new discussion in jBPM at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]