8 Replies Latest reply on Feb 15, 2006 10:52 AM by iterrell

    Timer to node to timer trouble

    iterrell

      Ok, here's the situation.

      I have a process that relies heavily on timers. In fact, the business process looks something like: do something, do something else after 10 days, do something else after 10 more days, etc. Some of the somethings are automated (node), and some are not (tasknode).

      My specific problem is that I have a node that 1) is entered by a timer, 2) leaves on its own, and 3) enters a node with a timer.

      Process snippet describing 1 and 3:

       <state name="wait1">
       <timer duedate="10 seconds" transition="continue" />
       <transition name="continue" to="mynode" />
       </state>
       <node name="mynode">
       <action class="foo.MyActionHandler" />
       <transition to="wait2" />
       </node>
       <state name="wait2">
       <timer duedate="20 seconds" transition="continue" />
       <transition name="continue" to="anotherstate" />
       </state>
      


      Part 2:
       public void execute(ExecutionContext ctx) throws Exception {
       log.debug("Executing mynode");
       ctx.leaveNode();
       }
      


      Executing it as such creates wait2's timer, but does not save it (as referenced in other threads http://www.jboss.com/index.html?module=bb&op=viewtopic&t=69040). If I take the advice given in that thread and save it explicitly with anything that comes from JbpmSession.getCurrentJbpmSession() then I get a StaleStateException from wait1's timer.

      For instance, if I do:
       public void execute(ExecutionContext ctx) throws Exception {
       log.debug("Executing mynode");
       ctx.leaveNode();
       JbpmUtil.saveProcessInstanceFamily(JbpmSession.getCurrentJbpmSession().getGraphSession(),ctx.getProcessInstance());
       }
      


      with JbpmUtil.saveProcessInstanceFamily():
       public static void saveProcessInstanceFamily(GraphSession graphSession, ProcessInstance processInstance) {
       // save family:
       Token token = processInstance.getRootToken();
       log.debug("saving process instance #" + processInstance.getId());
       graphSession.saveProcessInstance(processInstance);
       if (token.hasParent()) {
       ProcessInstance pi = token.getParent().getProcessInstance();
       log.debug("saving process instance #" + pi.getId());
       graphSession.saveProcessInstance(pi);
       }
       ProcessInstance sub = token.getSubProcessInstance();
       if (sub != null) {
       log.debug("saving process instance #" + sub.getId());
       graphSession.saveProcessInstance(sub);
       }
       }
      


      then I get:
      2006-02-10 14:48:34,253 DEBUG [foo.MyActionHandler] Executing mynode
      2006-02-10 14:48:34,269 DEBUG [org.jbpm.graph.def.GraphElement] event 'node-leave' on 'Node(mynode)' for 'Token(/)'
      2006-02-10 14:48:34,269 DEBUG [org.jbpm.graph.def.GraphElement] event 'transition' on 'Transition(1c71a93)' for 'Token(/)'
      2006-02-10 14:48:34,269 DEBUG [org.jbpm.graph.def.GraphElement] event 'node-enter' on 'State(wait2)' for 'Token(/)'
      2006-02-10 14:48:34,284 DEBUG [org.jbpm.graph.def.GraphElement] executing action 'CreateTimerAction(12d12e0)'
      2006-02-10 14:48:34,331 DEBUG [org.jbpm.db.SchedulerSession] saving timer timer(wait2,14:48:54,284)
      2006-02-10 14:48:34,363 DEBUG [org.jbpm.graph.def.GraphElement] event 'after-signal' on 'State(wait1)' for 'Token(/)'
      2006-02-10 14:48:34,363 DEBUG [com.gallium.jas.services.workflow.impl.SchedulerBean] deleting timer 'timer(wait1,14:48:34,000)'
      2006-02-10 14:48:34,394 ERROR [org.hibernate.jdbc.AbstractBatcher] Exception executing batch:
      org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
      


      Can anyone offer any advice?

      Ian

        • 1. Re: Timer to node to timer trouble
          iterrell

          Any chance anyone thought about this over the weekend and came up with some great insight? :)

          • 2. Re: Timer to node to timer trouble
            koen.aers

            Hi Ian,

            What version of jBPM are you using?

            Regards,
            Koen

            • 3. Re: Timer to node to timer trouble
              iterrell

              3.0.2 right now.

              I may try to migrate my existing code to 3.1 though, to see if I still have trouble there.

              Ian

              • 4. Re: Timer to node to timer trouble
                mennen

                Hi,

                I am using jbpm 3.0.2 with jboss 4.0.3 with mysql database.
                I am getting the following error when the timer is fired:

                16:34:32,794 WARN [Timer] timer action threw exception
                java.lang.NullPointerException
                 at org.jbpm.mennen.DoNothing.execute(DoNothing.java:25)
                 at org.jbpm.graph.def.Action.execute(Action.java:79)
                 at org.jbpm.scheduler.exe.Timer.execute(Timer.java:61)
                 at org.jbpm.scheduler.impl.SchedulerThread.executeTimers(SchedulerThread
                .java:81)
                 at org.jbpm.scheduler.impl.SchedulerThread.run(SchedulerThread.java:34)
                16:34:32,904 INFO [STDOUT] Hibernate: select exceptionh0_.NODE_ as NODE7_1_, ex
                ceptionh0_.ID_ as ID1_1_, exceptionh0_.GRAPHELEMENTINDEX_ as GRAPHELE6_1_, excep
                tionh0_.ID_ as ID1_233_0_, exceptionh0_.EXCEPTIONCLASSNAME_ as EXCEPTIO2_233_0_,
                 exceptionh0_.TYPE_ as TYPE3_233_0_, exceptionh0_.GRAPHELEMENT_ as GRAPHELE4_233
                _0_ from JBPM_EXCEPTIONHANDLER exceptionh0_ where exceptionh0_.NODE_=?
                16:34:32,974 INFO [STDOUT] Hibernate: select exceptionh0_.PROCESSDEFINITION_ as
                 PROCESSD5_1_, exceptionh0_.ID_ as ID1_1_, exceptionh0_.GRAPHELEMENTINDEX_ as GR
                APHELE6_1_, exceptionh0_.ID_ as ID1_233_0_, exceptionh0_.EXCEPTIONCLASSNAME_ as
                EXCEPTIO2_233_0_, exceptionh0_.TYPE_ as TYPE3_233_0_, exceptionh0_.GRAPHELEMENT_
                 as GRAPHELE4_233_0_ from JBPM_EXCEPTIONHANDLER exceptionh0_ where exceptionh0_.
                PROCESSDEFINITION_=?
                16:34:32,985 ERROR [Timer] unhandled timer exception
                org.jbpm.graph.def.DelegationException
                 at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:299)
                
                 at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:293)
                
                 at org.jbpm.scheduler.exe.Timer.execute(Timer.java:71)
                 at org.jbpm.scheduler.impl.SchedulerThread.executeTimers(SchedulerThread
                .java:81)
                 at org.jbpm.scheduler.impl.SchedulerThread.run(SchedulerThread.java:34)
                Caused by: java.lang.NullPointerException
                 at org.jbpm.mennen.DoNothing.execute(DoNothing.java:25)
                 at org.jbpm.graph.def.Action.execute(Action.java:79)
                 at org.jbpm.scheduler.exe.Timer.execute(Timer.java:61)
                 ... 2 more



                Here is the code of the process definition:
                <process-definition name="TestingTimers">
                
                 <swimlane name="tester">
                 <assignment expression="user(mennen)"></assignment>
                 </swimlane>
                
                
                 <start-state name="tester Timer 2">
                 <task swimlane="tester">
                 <controller>
                 <variable name="Comments"/>
                 </controller>
                 </task>
                 <transition name="" to="state1"></transition>
                 </start-state>
                
                 <state name="state1">
                 <timer name='reminder'
                 duedate='60 business seconds'
                 repeat='10 business seconds'
                 transition='end2'>
                 <action class='org.jbpm.mennen.DoNothing' />
                 </timer>
                 <transition name="" to="end1"></transition>
                 </state>
                
                 <end-state name="end1"></end-state>
                 <end-state name="end2"></end-state>
                
                </process-definition>
                


                Thanks in advance

                Mennen

                • 5. Re: Timer to node to timer trouble
                  mennen

                  forgot to add my action:

                  public class DoNothing implements ActionHandler {
                  
                   private static final long serialVersionUID = 1L;
                  
                   String swimlane;
                  
                   public void execute(ExecutionContext executionContext) throws Exception {
                  
                   String actorId = executionContext.getTaskMgmtInstance()
                   .getSwimlaneInstance(swimlane)
                   .getActorId();
                  
                   String taskName = executionContext.getTaskInstance().getName();
                  
                   Date d = executionContext.getTaskInstance().getDueDate();
                  
                   log.info("***********************************************");
                   log.info("*** "+actorId+", task '"+taskName+"' is waiting for you.");
                   log.info("*** the due date is :'"+d.toString()+"'");
                   log.info("***********************************************");
                  
                   }
                  
                   private static final Log log = LogFactory.getLog(DoNothing.class);
                  }
                  


                  • 6. Re: Timer to node to timer trouble
                    iterrell

                    mennen: I do believe you should post further questions about this in a new thread; your problem appears unrelated to mine.

                    But. I'm not a jBPM expert by any means, but my guess is that since the action DoNothing is associated with the timer in state1, and not directly with the task you define, the method

                    executionContext.getTaskInstance()

                    is returning null. Calling a further method on it (getName()) will throw a null pointer exception.

                    Ian

                    • 7. Re: Timer to node to timer trouble
                      koen.aers

                      Ian,

                      I would advise you to try the yesterday released 3.1 first, if this is at all possible for you.

                      Regards,
                      Koen

                      • 8. Re: Timer to node to timer trouble
                        iterrell

                        Koen,

                        3.1 seems to solve this problem. Thanks!

                        Ian