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 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>
<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...