2 Replies Latest reply on Jan 12, 2010 3:30 AM by neshap

    Finding and signalling custom behaviour

      === Environment ==============================
      - jBPM Version : tested on 4.1 through 4.3
      - Database : HSQLDB
      - JDK : 1.6.0_14
      - Container : No container , running as junit test
      - Configuration : No custom libs or cfg file

       

      === Process ==================================
      Main Process
      <?xml version="1.0" encoding="UTF-8"?>
      <process name="CustomActivityTest" xmlns="http://jbpm.org/4.3/jpdl">
         <start g="0,77,48,48" name="start1">
            <transition g="-27,-19" name="to Foo" to="Foo"/>
         </start>
         <sub-process g="241,237,168,52" name="BarSubprocess" sub-process-key="BarSubProcess">
            <transition g="-5,3" name="to HumanTask" to="HumanTask"/>
         </sub-process>
         <java class="com.application.workflow.JavaAutoActivity" g="98,74,112,52" method="doFoo" name="Foo">
            <transition g="-26,-39" name="to BarSubprocess" to="BarSubprocess"/>
         </java>
        <task assignee="fooOfficer" g="445,78,92,52" name="HumanTask">
            <transition g="-45,11" name="customTask" to="CustomTask"/>
         </task>
            <custom class="com.application.workflow.ExternalCustomState" g="629,81,92,52" name="CustomTask">
            <transition g="-31,10" name="endCustom" to="endCustom"/>
         </custom>
         <end g="810,84,48,48" name="endCustom"/>
      </process>

       

      SubProcess
      <?xml version="1.0" encoding="UTF-8"?>
      <process name="BarSubProcess" xmlns="http://jbpm.org/4.3/jpdl" key="BarSubProcess">
         <start name="start1" g="153,36,48,48">
            <transition name="toBar" to="Bar" g="-56,-20"/>
         </start>
         <java name="Bar" g="131,116,92,52" class="com.application.workflow.JavaAutoActivity" method="doBar">
            <transition name="to Approve" to="Approve" g="-75,-20"/>
         </java>
         <end name="endBar" g="154,310,48,48"/>
         <task name="Approve" g="130,222,92,52" assignee="barOfficer">
            <transition name="endBar" to="endBar" g="-54,11"/>
         </task>
      </process>

       

      === API ===================================
      public class ExternalCustomState implements ExternalActivityBehaviour {

       

          private static final long serialVersionUID = -392570865173037816L;

       

          @Override
          public void signal(ActivityExecution execution, String signalName,
                  Map<String, ?> parameters) throws Exception {
              System.out.println("Signal name for ExternalCustomState: "+signalName);
              execution.take(signalName);

       

          }

       

          @Override
          public void execute(ActivityExecution execution) throws Exception {
              System.out.println("ExternalCustomState: Process in execute method");
              execution.waitForSignal();
          }

       

      }

       

      public class JavaAutoActivity {
         
          public void doFoo(){
              System.out.println("JavaAutoActivity : Foo is done");
          }

       

          public void doBar(){
              System.out.println("JavaAutoActivity : Bar is done");
          }
      }

       


      public void testProcess() throws Exception {
             
              ProcessInstance instance = executionService.startProcessInstanceByKey("CustomActivityTest",null,"A001");
              String pid = instance.getId();
             
              //SubProcess task
              List<Task> tasksList1 = taskService.findPersonalTasks("barOfficer");
              Task task1 = tasksList1.get(0);
              taskService.completeTask(task1.getId(), "endBar");
             
              //Human Task
              tasksList1 = taskService.findPersonalTasks("fooOfficer");
              task1 = tasksList1.get(0);
              taskService.completeTask(task1.getId(), "customTask");
             
              //Custom Activity search
              //This is the problem
              Execution customTask=instance.findActiveExecutionIn("CustomTask");
              if(customTask==null){
              System.out.println("Custom Activity is NULL");}

       

              //Active task should be CustomTask not SubProcess !!!?
              System.out.println("Process instance in CustomTask ? : "+instance.isActive("CustomTask"));
              System.out.println("Process instance in BarSubprocess ? : "+instance.isActive("BarSubprocess"));
                     
              customTask=instance.findActiveExecutionIn("BarSubprocess");
             
              //Custom task is signaled ?
              executionService.signalExecutionById(customTask.getId(),"endCustom");

       

              HistoryProcessInstance historyInstance = historyService.createHistoryProcessInstanceQuery()
                                                  .processInstanceId(pid).uniqueResult();
         
              //Print history
              HistoryActivityInstanceQuery activityq=historyService.createHistoryActivityInstanceQuery();
              List<HistoryActivityInstance> activities=activityq.list();
              for (HistoryActivityInstance historyActivityInstance : activities) {
                  System.out.println("Activity "+historyActivityInstance.getActivityName()+ " duration "
                          +historyActivityInstance.getDuration()+" started on "+
                          historyActivityInstance.getStartTime()+ " ended on "+historyActivityInstance.getEndTime());
              }
             
             
              assertEquals("ended", historyInstance.getState());
          }

       

      === Debug logs ==============================
      12:03:04,071 FIN | [ProcessDefinitionImpl] creating new execution for process 'CustomActivityTest'
      12:03:04,074 FIN | [DatabaseIdComposer] generated execution id CustomActivityTest.A001
      12:03:04,078 FIN | [ExecuteActivity] executing activity(start1)
      12:03:04,078 FIN | [ExecuteActivity] executing activity(Foo)
      JavaAutoActivity : Foo is done
      12:03:04,082 FIN | [ExecuteActivity] executing activity(BarSubprocess)
      12:03:04,096 FIN | [ProcessDefinitionImpl] creating new execution for process 'BarSubProcess'
      12:03:04,096 FIN | [DatabaseIdComposer] generated execution id BarSubProcess.15
      12:03:04,107 FIN | [ExecuteActivity] executing activity(start1)
      12:03:04,108 FIN | [ExecuteActivity] executing activity(Bar)
      JavaAutoActivity : Bar is done
      12:03:04,108 FIN | [ExecuteActivity] executing activity(Approve)
      12:03:04,164 FIN | [Signal] signalling activity(Approve), signalName=endBar
      12:03:04,173 FIN | [ExecuteActivity] executing activity(endBar)
      12:03:04,174 FIN | [ExecutionImpl] execution[BarSubProcess.15] ends with state ended
      12:03:04,194 FIN | [Signal] signalling activity(BarSubprocess), signalName=null
      12:03:04,195 FIN | [ExecuteActivity] executing activity(HumanTask)
      12:03:04,218 FIN | [Signal] signalling activity(HumanTask), signalName=customTask
      12:03:04,219 FIN | [ExecuteActivity] executing activity(CustomTask)
      ExternalCustomState: Process in execute method
      Custom Activity is NULL
      Process instance in CustomTask ? : false
      Process instance in BarSubprocess ? : true
      12:03:04,226 FIN | [Signal] signalling activity(CustomTask), signalName=endCustom
      Signal name for ExternalCustomState: endCustom
      12:03:04,226 FIN | [ExecuteActivity] executing activity(endCustom)
      12:03:04,226 FIN | [ExecutionImpl] execution[CustomActivityTest.A001] ends with state ended
      12:03:04,235 FIN | [DbSessionImpl] deleting process instance CustomActivityTest.A001
      Activity Foo duration 3 started on 2010-01-11 12:03:04.078 ended on 2010-01-11 12:03:04.081
      Activity BarSubprocess duration 105 started on 2010-01-11 12:03:04.089 ended on 2010-01-11 12:03:04.194
      Activity Bar duration 0 started on 2010-01-11 12:03:04.108 ended on 2010-01-11 12:03:04.108
      Activity Approve duration 51 started on 2010-01-11 12:03:04.108 ended on 2010-01-11 12:03:04.159
      Activity HumanTask duration 19 started on 2010-01-11 12:03:04.195 ended on 2010-01-11 12:03:04.214

       

      === Problem description =========================
      I have a problem with custom activities that implement ExternalActivityBehaviour (beside JIRA issue with history and custom activities).
      In process definition, custom task is the last activity in process. But I can't find it or signal it by name (see Custom Activity search).
      Instead of finding CustomTask, process instance reports that active execution is still in subprocess BarSubProcess (although subprocess has ended, and the task HumanTask that follows it has also ended), but I can signal it with transition of the CustomTask.

      So to put it simple, I haven't managed to find a way to find and signal custom activity through activityName.
      Anyone has run into this problem? I've searched jBPM JIRA but haven't found nothing related to this.

        • 1. Re: Finding and signalling custom behaviour
          kukeltje

          The processinstance object is 'detached' from the database, so updates to it (e.g. ending tasks) are not visible in it. Retrieve it again using the executionservice to see changes. In contrast to jBPM 3, you should not use services to interact with the engine/processinstance and not the objeccts from the model. See all unittests in the sourcecode for LOTS of examples....

           

          edit: should of-course be "use services" and not "not use services"

          • 2. Re: Finding and signalling custom behaviour
            Thanks Ronald. Couldn't see the forest for the trees.