1 2 Previous Next 23 Replies Latest reply on May 7, 2010 10:46 PM by rebody

    Problem Signaling a Waiting Execution

      I'm having trouble signaling a process instance to advance beyond a wait activity.  I've looked at the jBPM example but no luck.  I have a process definition with numerous state activities.  I created a lisetner for each activity.  The listeners (simulate) some external work then call the executionService.signalExecutionById() method:


          public void notify(EventListenerExecution execution) throws Exception {
             
              System.out.println("MESSAGE: " + msg);
         
              //Timer timer = new Timer();
              //ExternalTaskProxy task = new ExternalTaskProxy();
              //Date now = new Date();
              //timer.schedule(task, now, 1500);
                    

              ProcessEngine processEngine = new Configuration()
                 .buildProcessEngine();


              ExecutionService executionService = processEngine.getExecutionService();
              executionService.signalExecutionById(execution.getId());
          }

       

       

      I deploy the business archive using an Ant script then run a process instance via the jBPM console.  The process instance starts but halts at the first activity.  Here's the process definition's jpdl code look like this:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <process name="Simple Activity Scheduling" xmlns="http://jbpm.org/4.0/jpdl">
         <start g="188,25,48,48" name="start">
            <transition g="-110,-11" name="to Activity1" to="
      Activity1"/>
         </start>
         <state g="137,123,150,52" name="
      Activity1">
              <on event="end">
              <event-listener class="my.package.MyListener1"/>
              </on>
            <transition name="to
      Activity2" to="Activity2" g="-138,-18"/>
         </state>
        
         <state g="137,220,152,52" name="
      Activity2">
              <on event="end">
              <event-listener class="
      my.package.MyListener2"/>
              </on>
            <transition name="to
      Activity3" to="Activity3" g="-153,-18"/>
         </state>
         <state g="128,322,170,52" name="
      Activity3">
              <on event="end">
              <event-listener class="
      my.package.MyListener3"/>
              </on>
            <transition name="to
      Activity4" to="Activity4" g="-129,-18"/>
         </state>
         <state g="141,420,142,52" name="
      Activity4">
              <on event="end">
              <event-listener class="
      my.package.MyListener4"/>
              </on>
            <transition name="to
      Activity5" to="Activity5" g="-150,-18"/>
         </state>
         <state g="129,527,168,52" name="
      Activity5">
              <on event="
      end">
              <event-listener class="
      my.package.MyListener5"/>
              </on>
            <transition name="to
      Activity6" to="Activity6" g="-137,-18"/>
         </state>
         <state g="127,632,170,52" name="
      Activity6">
              <on event="
      end">
              <event-listener class="
      my.package.MyListener6"/>
              </on>
            <transition name="to
      Activity7" to="Activity7" g="-46,-18"/>
         </state>
         <state g="165,739,92,52" name="
      Activity7">
              <on event="
      end">
              <event-listener class="
      my.package.MyListener7"/>
              </on>
            <transition name="to
      Activity8" to="Activity8" g="-130,-18"/>
         </state>
         <state g="142,846,139,52" name="
      Activity8">
              <on event="
      end">
              <event-listener class="
      my.package.MyListener8"/>
              </on>
            <transition name="to end" to="end" g="-36,-18"/>
         </state>
         <end g="651,849,48,48" name="end"/>
      </process>

       

      Any help would be appreciated.

        • 1. Re: Problem Signaling a Waiting Execution

          Did you know if your listener is executed? Maybe you should change the time of the listener execution! Change it from "end" to "start". It is an attempt only.

           

          Best regards

          • 2. Re: Problem Signaling a Waiting Execution
            saraswati.santanu

            This one looks incorrect. As result of one signal to the flow you arrived at the event listener. You are yet to move to the next node. Then you call signal again. So when you make this signal at that point of time you are still in your previous node. What should be the rational outcome is something I am not sure of.

             

            It will be good to understand what are you trying to achieve. If you do not want to wait at the next node and want it to exit (and fire 'exit' event to fire) as soon as you move there then you should not be using signal node.

            • 3. Re: Problem Signaling a Waiting Execution

              Hmmm.  Perhaps my understanding of jBPM is flawed.  Here's what I am trying to do:  Every state activity of the process definition represents a piece of external work that needs to be performed.  That is by I have a separate event listener class for each step.  The idea is to kick of the external work within the event listener.  When it's done, I understood that calling executionService.signalExecutionById(executionId); method signals the ProcessEngine to advance the process instance to the next step.  So, in my example, the ProcessEngine halts execution on Activity1 since it is a state.  I figured that by calling the executionService.signalExecutionById(executionId); method in the event listener for that state signals the ProcessEngine to advance to Activity2. Is this not correct?

              • 4. Re: Problem Signaling a Waiting Execution
                Thanks for the suggestion, Dominic.  Unfortunately, I already tried that.  jBPM throws an exception whn I do that.
                • 5. Re: Problem Signaling a Waiting Execution
                  saraswati.santanu

                  These are the two points I understood about your requirement:

                   

                  1. You have to perform some activity at every node of the flow.

                   

                  2. You call executionService.signalExecutionById(executionId); from somewhere outside to invoke the flow for the first time. This call takes you to the end even listener of activity1. There you try to invoke executionService.signalExecutionById(executionId); to ensure that you move to activity2.

                   

                  Lets take the second point first. Hope this understanding of mine is correct. And if it is correct then you do not need executionService.signalExecutionById(executionId); call in your event listener. If you have reached end event listener you will anyway move to the next activity (activity2). Just execute your business logic there. Flow will be taken care of.

                   

                  About the first point - my question is do you need to wait for some external operation (which is not a part of the flow) to happen and then trigger the flow at each activity? If you need to do this then state node is the correct choice. If you do not need to wait at the node and just need to execute some business logic at the node you should consider using java node.

                  • 6. Re: Problem Signaling a Waiting Execution

                    Oh, Santanu is right! You should use a state-node only when you need to execute some external work. The event listener is not responsible for signaling the waiting state. The external code is responsible! I think you can use the event listener to save the right execution id, so you know in your external code the execution id which you want to signal.

                     

                    See for more information: http://docs.jboss.com/jbpm/v4/userguide/html_single/#singallingawaitingexecution

                     

                    Best regards

                    • 7. Re: Problem Signaling a Waiting Execution
                      Fair enough.  Just to clarify, I have been using a state-node.  I refactored the code to do all external work and then signal the ProcessEngine when done in another class that the listener instantiates.  I'm still getting the same exeption.  You guys did bring up a good point:  I have an idea that I may be passing on the wrong ID to the  executionService.signalExecutionById()method.  From what I understand, you are suppoed to be paasing on the current process instance's execution ID.  Is that correct?
                      • 8. Re: Problem Signaling a Waiting Execution
                        kukeltje

                        You should pass on the id that is required. A process is an execution, but an execution does not need to be a process. The best example is when a fork is used. Each leg has its own execution... So passing on the execution ID is the safest thing to do. But an execution can have multiple activities. So if you want to signal/end just one of those, you might need to pass on the activity id.

                        • 9. Re: Problem Signaling a Waiting Execution

                          Ronald,

                           

                          I think you are on to something.  Here's the issue.  I have a Process Definition with 8 steps (i.e activities) in it (Activity1 through Activity8).  Each step is a state.  When I create a instance of the Process Definition, I get the exception because programatically, the API only recognizes the first activity (state) so when I signal the ProcessEngine to advance, there is nothing to advance to.  Here's how I tested it where's as the  executionListener variable is an instance to the EventListenerExecution that is passed as an argument in my Listener class:

                           

                                  System.out.println("CURRENT EXECUTION NAME: " + executionListener.getName());
                                  System.out.println("CURRENT EXECUTION ID: " + executionListener.getId());
                                  System.out.println("CURRENT EXECUTION KEY: " + executionListener.getKey());
                                  System.out.println("CURRENT EXECUTION STATE: " + executionListener.getState());
                                  System.out.println("CURRENT EXECUTION PRIORITY: " + executionListener.getPriority());
                                  System.out.println("IS PROCESS INSTANCE: " + executionListener.getIsProcessInstance());
                                 
                                  Set<String> s = executionListener.findActiveActivityNames();
                                  Iterator<String> i = s.iterator();
                                 
                                  while(i.hasNext()) {
                                      String activity = i.next();
                                      System.out.println("ACTIVITY NAME IN SET [CURRENT]: " + activity);
                                  }

                           

                          Outputs:

                           

                          1. I know the ExecutionListener is a ProcessInstance since the  executionListener.getIsProcessInstance()returns 'true'

                          2.  There is only one activity (Activity1) in the Set that is returned from executionListener.findActiveActivityNames()method even though (as you can see in the JPDL code below), there are 8 activities.

                           

                          JPDL code:

                           

                          <?xml version="1.0" encoding="UTF-8"?>
                          <process name="Simple Activity Scheduling" xmlns="http://jbpm.org/4.0/jpdl">
                             <start g="188,25,48,48" name="start">
                                <transition g="-110,-11" name="to Activity1" to="
                          Activity1"/>
                             </start>
                             <state g="137,123,150,52" name="
                          Activity1">
                                  <on event="end">
                                  <event-listener class="my.package.MyListener1"/>
                                  </on>
                                <transition name="to
                          Activity2" to="Activity2" g="-138,-18"/>
                             </state>
                            
                             <state g="137,220,152,52" name="
                          Activity2">
                                  <on event="end">
                                  <event-listener class="
                          my.package.MyListener2"/>
                                  </on>
                                <transition name="to
                          Activity3" to="Activity3" g="-153,-18"/>
                             </state>
                             <state g="128,322,170,52" name="
                          Activity3">
                                  <on event="end">
                                  <event-listener class="
                          my.package.MyListener3"/>
                                  </on>
                                <transition name="to
                          Activity4" to="Activity4" g="-129,-18"/>
                             </state>
                             <state g="141,420,142,52" name="
                          Activity4">
                                  <on event="end">
                                  <event-listener class="
                          my.package.MyListener4"/>
                                  </on>
                                <transition name="to
                          Activity5" to="Activity5" g="-150,-18"/>
                             </state>
                             <state g="129,527,168,52" name="
                          Activity5">
                                  <on event="
                          end">
                                  <event-listener class="
                          my.package.MyListener5"/>
                                  </on>
                                <transition name="to
                          Activity6" to="Activity6" g="-137,-18"/>
                             </state>
                             <state g="127,632,170,52" name="
                          Activity6">
                                  <on event="
                          end">
                                  <event-listener class="
                          my.package.MyListener6"/>
                                  </on>
                                <transition name="to
                          Activity7" to="Activity7" g="-46,-18"/>
                             </state>
                             <state g="165,739,92,52" name="
                          Activity7">
                                  <on event="
                          end">
                                  <event-listener class="
                          my.package.MyListener7"/>
                                  </on>
                                <transition name="to
                          Activity8" to="Activity8" g="-130,-18"/>
                             </state>
                             <state g="142,846,139,52" name="
                          Activity8">
                                  <on event="
                          end">
                                  <event-listener class="
                          my.package.MyListener8"/>
                                  </on>
                                <transition name="to end" to="end" g="-36,-18"/>
                             </state>
                             <end g="651,849,48,48" name="end"/>
                          </process>

                          • 10. Re: Problem Signaling a Waiting Execution
                            walterjs

                            So it looks like you have 8 sequential activities. Only one of them will be active at a time. To move to the next activity, you need to signal the execution. If these were tasks, you would call completeTask on each instance as they are completed and the next activity will become active.

                             

                            Hope this helps

                            Walter

                            • 11. Re: Problem Signaling a Waiting Execution
                              saraswati.santanu

                              Well Andy,

                                  I am not very sure how are you trying to do this. Let me explain what I think you should be doing.

                               

                                  But before that, your doubt about executionListener.findActiveActivityNames() method. This is "active" activity names. And you have only one active acitvity. I do not think there is any API to find all the activitiy names present in the JPDL.

                               

                                  Assuming you will need all of your node to be state nodes, you will need two sets of classes an external class which triggers the flow when required, and few event listener classes whcih will perform the business logic. Below is a sample of how both the classes should look like:

                               

                                  Class external to the flow that triggers the flow:

                               

                                  private void signalWorkFlow(ProcessInstance processInstance) {

                                       //signal flow to execute Activity1. The flow will stop at Activity2

                                       String stateName = "Activity1";

                                       Execution execution = processInstance.findActiveExecutionIn(stateName);

                                       processInstance = executionService.signalExecutionById(execution.getId());


                                       //signal flow to execute Activity2. The flow will stop at Activity3

                                       String stateName = "Activity2";

                                       Execution execution = processInstance.findActiveExecutionIn(stateName);

                                       processInstance = executionService.signalExecutionById(execution.getId());


                                        ....

                                        ....

                                        .... till Activity8

                                  }

                               

                                  And the event listener will be something like:

                               

                                  public void notify(EventListenerExecution execution) throws Exception {
                                       //Execute business logic...

                                      //Important to note that you do not call signalXXX here, neither from any other class which you call from here

                                  }

                               

                                  Also please check if you really need so many state nodes or you need java node, task node etc. Every node has its own purpose. And you will be the best judge to see which node exactly fits your requirement.

                              • 12. Re: Problem Signaling a Waiting Execution
                                kukeltje

                                @Andy,

                                 

                                Saraswati Santanu is right in suggesting a different approach. You have overcomplicated your solution and implemented, or tried implementing something in a way that is from what I know never done this way. None of the examples, testcases, tutorials etc suggest doing what you do. This makes me wonder if you have a background in a different workflow/bpm platform or if e.g. you have taken over a project from someone else.

                                 

                                What I'd suggest is to at least read some documentation on jBPM4, look at examples/testcases in the source to get a grip with what does what. Besides the suggestions of java 'tasks' maybe custom nodes are also interesting for you to use, but completely depending on what your usecase is. What realy is important is to see if you need everything to be synchronous like you have now, or that the external service you call is kind of long running (>more then several seconds) so you should use async functionality where the called service signals the process instance. So please think of your architecture first and implentation later.

                                 

                                Ronald

                                • 13. Re: Problem Signaling a Waiting Execution

                                  Thanks for all of the input folks.  Ronald, just to clarify I have read the jBPM documentation - over and over and this is my first exposure to BPM technology, at least from a developer's point of view (I did the Systems Engineering in a project that used Oracle's BPM technology).  I suppose you are correct; BPM does not jive with my notion I have of a traditional "workflow".   Given my example, I do not understand how jBPM is supposed to work.  For example, why does jBPM equate an Execution to a Process Instance?  To me, a process instance should be a run of the entire Process Definition, i.e. "workflow" (all the "actvities" or "steps") and an Execution is simply the node ("activity" or "step") that is currently being executed.

                                   

                                  The jBPM documentation (as well as you guys) reference external Java classes that "control" the workflow execution outside of the listeners. That's probably where I made my mistake.  I think you guys are correct;  I need to back up and re-think my strategy.  Again, thanks to evryone for the help.  Much approeciated.

                                  • 14. Re: Problem Signaling a Waiting Execution
                                    kukeltje

                                    Andy,

                                     

                                    No sweat, and I certainly did not want to offend you in any way. It's just that I've never seen anyone (try to) use jBPM like this.

                                     

                                    Regarding executions/processinstances et al.

                                     

                                    Executions kind of travel trough the process like tokens in petri nets (in jBPM 3 they were called tokens). If there are no forks etc, there is only one root execution that at the same time is the equivalent of the process instance. When you do have forks, there are multiple executions each referencing a parent. Activities are what is done when the execution reaches a node.

                                     

                                    hope this helps (a little)

                                    1 2 Previous Next