org.jbpm.workflow.instance.node.DynamicUtils, method internalAddDynamicWorkItem
zhangjing2000 Jan 11, 2014 1:04 AMWhen I tried to make some changes on ProcessInstanceManager to keep a memory copy of processInstance longer than a command's cycle, I ran into a problem in method internalAddDynamicWorkItem from class org.jbpm.workflow.instance.node.DynamicUtils. See below the highlighted section.
private static void internalAddDynamicWorkItem(
final WorkflowProcessInstance processInstance, final DynamicNodeInstance dynamicContext,
KieRuntime ksession, String workItemName, Map<String, Object> parameters) {
final WorkItemImpl workItem = new WorkItemImpl();
workItem.setState(WorkItem.ACTIVE);
workItem.setProcessInstanceId(processInstance.getId());
workItem.setName(workItemName);
workItem.setParameters(parameters);
// this code snippet will add workItemNodeInstance into processInstance. But it will cause issues if kession is a Command Session.
final WorkItemNodeInstance workItemNodeInstance = new WorkItemNodeInstance();
workItemNodeInstance.setNodeInstanceContainer(dynamicContext == null ? processInstance : dynamicContext);
workItemNodeInstance.setProcessInstance(processInstance);
workItemNodeInstance.internalSetWorkItem(workItem);
workItemNodeInstance.addEventListeners();
if (ksession instanceof StatefulKnowledgeSessionImpl) {
executeWorkItem((StatefulKnowledgeSessionImpl) ksession, workItem, workItemNodeInstance);
} else if (ksession instanceof CommandBasedStatefulKnowledgeSession) {
CommandService commandService = ((CommandBasedStatefulKnowledgeSession) ksession).getCommandService();
commandService.execute(new GenericCommand<Void>() {
private static final long serialVersionUID = 5L;
public Void execute(Context context) {
StatefulKnowledgeSession ksession = (StatefulKnowledgeSession) ((KnowledgeCommandContext) context).getKieSession();
// if realProcessInstance is actually the same as processInstance, the code snippet below will add a second copy of workItemNodeInstance into processInstance.
// in current jBPM implementation, this won't happen, as realProcessInstance is always a new java object, but it will if there is a cached processInstance in ksession or ProcessInstanceManager -- I altered jBPM source code to make this happened.
WorkflowProcessInstance realProcessInstance = (WorkflowProcessInstance) ksession.getProcessInstance(processInstance.getId());
workItemNodeInstance.setProcessInstance(realProcessInstance);
if (dynamicContext == null) {
workItemNodeInstance.setNodeInstanceContainer(realProcessInstance);
} else {
DynamicNodeInstance realDynamicContext = findDynamicContext(realProcessInstance, dynamicContext.getUniqueId());
workItemNodeInstance.setNodeInstanceContainer(realDynamicContext);
}
executeWorkItem((StatefulKnowledgeSessionImpl) ksession, workItem, workItemNodeInstance);
return null;
}
});
} else {
throw new IllegalArgumentException("Unsupported ksession: " + ksession == null ? "null" : ksession.getClass().getName());
}
}