0 Replies Latest reply on Jan 11, 2014 1:04 AM by zhangjing2000

    org.jbpm.workflow.instance.node.DynamicUtils, method internalAddDynamicWorkItem

    zhangjing2000

      When 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());

               }

        }