cancel
Showing results for 
Search instead for 
Did you mean: 

Simple flow with Timer not repeating

castyn
Champ in-the-making
Champ in-the-making
Hello all, I have a fairly simply process setup that gets an object, performs some logic via JavaDelegate tasks, and repeats if the process did not go through properly.  There is a 10 second wait as well. 

What I am observing happening is that after the notifySupervisorTask, the process exists and does not go through the timer or reenter the first task again.  I am not sure what I am doing wrong.  When deploying I am also seeing a warning

254 - org.activiti.engine - 5.17.0 | Error while generating process diagram, image will not be stored in repository
java.lang.IllegalArgumentException: input == null!
        at javax.imageio.ImageIO.read(ImageIO.java:1348)[:1.7.0_80]…


Not sure if it is related or not


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="assignServiceRequest" name="Assign Service Request" isExecutable="true">
    <startEvent id="start">
      <documentation>The start of this process is a task looking to be assigned</documentation>
    </startEvent>
    <serviceTask id="attendantDetailsTask" name="Check Attendents Details" activiti:class="com.vizexplorer.techviz.tasks.AttendantDetailsTask"></serviceTask>
    <sequenceFlow id="flow1" sourceRef="start" targetRef="attendantDetailsTask"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow2" sourceRef="attendantDetailsTask" targetRef="exclusivegateway1"></sequenceFlow>
    <serviceTask id="assignTaskToUserTask" name="Assign Task to Attendant" activiti:class="com.vizexplorer.techviz.tasks.AttendantAssignTask"></serviceTask>
    <sequenceFlow id="flow3" name="Attendants available in section" sourceRef="exclusivegateway1" targetRef="assignTaskToUserTask">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${attendantAvailable == true}]]></conditionExpression>
    </sequenceFlow>
    <serviceTask id="notifySupervisorTask" name="Notify Supervisor" activiti:class="com.vizexplorer.techviz.tasks.NotifySupervisorTask"></serviceTask>
    <sequenceFlow id="flow4" name="No attendants available" sourceRef="exclusivegateway1" targetRef="notifySupervisorTask">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${attendantAvailable == false}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow6" sourceRef="assignTaskToUserTask" targetRef="endevent1"></sequenceFlow>
    <intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent">
      <timerEventDefinition>
        <timeDuration>PT10S</timeDuration>
      </timerEventDefinition>
    </intermediateCatchEvent>
    <sequenceFlow id="flow7" sourceRef="notifySupervisorTask" targetRef="timerintermediatecatchevent1"></sequenceFlow>
    <sequenceFlow id="flow8" sourceRef="timerintermediatecatchevent1" targetRef="attendantDetailsTask"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_assignServiceRequest">
    <bpmndi:BPMNPlane bpmnElement="assignServiceRequest" id="BPMNPlane_assignServiceRequest">
      <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
        <omgdc:Bounds height="35.0" width="35.0" x="50.0" y="115.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="attendantDetailsTask" id="BPMNShape_attendantDetailsTask">
        <omgdc:Bounds height="65.0" width="105.0" x="160.0" y="100.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="340.0" y="112.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="assignTaskToUserTask" id="BPMNShape_assignTaskToUserTask">
        <omgdc:Bounds height="61.0" width="105.0" x="520.0" y="102.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="notifySupervisorTask" id="BPMNShape_notifySupervisorTask">
        <omgdc:Bounds height="55.0" width="105.0" x="308.0" y="240.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="750.0" y="115.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="timerintermediatecatchevent1" id="BPMNShape_timerintermediatecatchevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="195.0" y="250.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="85.0" y="132.0"></omgdi:waypoint>
        <omgdi:waypoint x="160.0" y="132.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="265.0" y="132.0"></omgdi:waypoint>
        <omgdi:waypoint x="340.0" y="132.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="380.0" y="132.0"></omgdi:waypoint>
        <omgdi:waypoint x="520.0" y="132.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="42.0" width="100.0" x="389.0" y="100.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="360.0" y="152.0"></omgdi:waypoint>
        <omgdi:waypoint x="360.0" y="240.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="42.0" width="100.0" x="369.0" y="169.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="625.0" y="132.0"></omgdi:waypoint>
        <omgdi:waypoint x="750.0" y="132.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="308.0" y="267.0"></omgdi:waypoint>
        <omgdi:waypoint x="230.0" y="267.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
        <omgdi:waypoint x="212.0" y="250.0"></omgdi:waypoint>
        <omgdi:waypoint x="212.0" y="227.0"></omgdi:waypoint>
        <omgdi:waypoint x="212.0" y="165.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>


5 REPLIES 5

castyn
Champ in-the-making
Champ in-the-making
A bit of follow up, I have the following beans configured as well.  When I remove the timer, the process completes as expected, just without the desired delay.  Seems like it should be the most simple case ever, but for some reason the process bails out (without any exceptions or warnings) with that timer there

<code>
  <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <property name="targetDataSource">
      <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        <property name="driverClass" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
        <property name="username" value="sa" />
        <property name="password" value="" />
      </bean>
    </property>
  </bean>

  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
  </bean>

  <bean id="asyncExecutor" class="org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor">
    <property name="defaultAsyncJobAcquireWaitTimeInMillis" value="1000" />
    <property name="defaultTimerJobAcquireWaitTimeInMillis" value="1000" />
  </bean>

  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="jobExecutorActivate" value="true" />
    <property name="asyncExecutor" ref="asyncExecutor" />
    <property name="asyncExecutorEnabled" value="true" />
    <property name="asyncExecutorActivate" value="false" />
  </bean>

  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>

  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
</code>

castyn
Champ in-the-making
Champ in-the-making
I have tried everything I can think of, pointing out that I am new to activiti.  I created a simple flow of task -> timer -> task, and after the timer the flow stops.  I have altered the configuration on the process engine through about every iteration of executor vs async executor enabling and disabling.  I am not sure what else I can try at this point.

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi Castyn,

have a look on the following jUnit test in the activiti source:
org.activiti.engine.test.bpmn.event.timer.IntermediateTimerEventTest#testCatchingTimerEvent

In the case when it does not work, create jUnit test:
http://forums.activiti.org/content/sticky-how-write-unit-test

Regards
Martin

castyn
Champ in-the-making
Champ in-the-making
This is largely for a proof of concept as we are evaluating a number of BPMN engines so I haven't had the time to devote to pulling out the base case of a catch timer into a unit test.  Also, that unit test as far as I can tell does not actually leverage a BPMN.xml or non default configuration and instead is just testing the underlying java code, which works.  This unit tests run fine when deployed and I have run all of the examples within the container as well.  I believe it is related to configuration that is likely causing the issue, and unit tests, at least in my experience, are poor representations of server side configuration issues and challenges.

I'll keep trying to pull it apart and can try to create an integration test (don't think unit will cut it for a task -> timer -> task example with custom config).  But my hopes are not very high at this point of having a breakthrough on the issue.  I may end up having to debug through the source code of the engine to understand why a timer catch event just ends an activiti process without any log message.

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi Castyn,

The unit test org.activiti.engine.test.bpmn.event.timer.IntermediateTimerEventTest#testCatchingTimerEvent uses following bpmn20 process model:

<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:activiti="http://activiti.org/bpmn"
             targetNamespace="Examples">

    <process id="intermediateTimerEventExample" name="Timer intermediate event example">

        <startEvent id="theStart"/>
        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="timer"/>

        <intermediateCatchEvent id="timer">
            <timerEventDefinition>
                <timeDuration>PT5M</timeDuration>
            </timerEventDefinition>
        </intermediateCatchEvent>

        <sequenceFlow id="flow2" sourceRef="timer" targetRef="theEnd"/>

        <endEvent id="theEnd"/>

    </process>
    <bpmndi:BPMNDiagram id="diagram">
       <bpmndi:BPMNPlane bpmnElement="intermediateTimerEventExample" id="intermediateTimerEventExample_di">
          <bpmndi:BPMNShape bpmnElement="theStart" id="theStart_di">
             <omgdc:Bounds height="30.0" width="30.0" x="114.0" y="185.0"/>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="timer" id="timer_di">
             <omgdc:Bounds height="30.0" width="30.0" x="195.0" y="185.0"/>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="theEnd" id="theEnd_di">
             <omgdc:Bounds height="28.0" width="28.0" x="270.0" y="186.0"/>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNEdge bpmnElement="flow1" id="flow1_di">
             <omgdi:waypoint x="144.0" y="200.0"/>
             <omgdi:waypoint x="195.0" y="200.0"/>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="flow2" id="flow2_di">
             <omgdi:waypoint x="225.0" y="200.0"/>
             <omgdi:waypoint x="270.0" y="200.0"/>
          </bpmndi:BPMNEdge>
       </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>

</definitions>

activiti engine configuration is:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="processEngineConfiguration"
    class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

   <property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
   <property name="jdbcDriver" value="org.h2.Driver" />
   <property name="jdbcUsername" value="sa" />
   <property name="jdbcPassword" value="" />

    <!– Database configurations –>
    <property name="databaseSchemaUpdate" value="drop-create" />

    <!– job executor configurations –>
    <property name="jobExecutorActivate" value="false" />
    <property name="asyncExecutor" ref="asyncExecutor" />
    <property name="asyncExecutorEnabled" value="true" />
    <property name="asyncExecutorActivate" value="false" />
   
    <property name="defaultFailedJobWaitTime" value="1" />
    <property name="asyncFailedJobWaitTime" value="1" />

    <!– mail server configurations –>
    <property name="mailServerPort" value="5025" />
   
    <property name="mailServers">
      <map>
        <entry key="myEmailTenant">
          <bean class="org.activiti.engine.cfg.MailServerInfo">
            <property name="mailServerHost" value="localhost" />
            <property name="mailServerPort" value="5025" />
            <property name="mailServerUseSSL" value="false" />
            <property name="mailServerUseTLS" value="false" />
            <property name="mailServerDefaultFrom" value="activiti@myTenant.com" />
            <property name="mailServerUsername" value="activiti@myTenant.com" />
            <property name="mailServerPassword" value="password" />
          </bean>
        </entry>
      </map>
    </property>
   
    <property name="history" value="full" />
  </bean>
 
  <bean id="asyncExecutor" class="org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor">
    <property name="defaultAsyncJobAcquireWaitTimeInMillis" value="1000" />
    <property name="defaultTimerJobAcquireWaitTimeInMillis" value="1000" />
  </bean>

</beans>

What the code really does :

@Deployment// deploys model to the engine (based on the testclass.method name (IntermediateTimerEventTest.testCatchingTimerEvent.bpmn20.xml)
  public void testCatchingTimerEvent() throws Exception {

    // Set the clock fixed
    Date startTime = new Date();

    // After process start, there should be timer created
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("intermediateTimerEventExample");
    JobQuery jobQuery = managementService.createJobQuery().processInstanceId(pi.getId());
    assertEquals(1, jobQuery.count());

    // After setting the clock to time '50minutes and 5 seconds', the second timer should fire
    processEngineConfiguration.getClock().setCurrentTime(new Date(startTime.getTime() + ((50 * 60 * 1000) + 5000))); // setting the time to the future (5 minutes) (yes activiti can work in virtual time)
    waitForJobExecutorToProcessAllJobs(5000L, 25L); // starts jobexecutor and process all jobs.

    assertEquals(0, jobQuery.count());
    assertProcessEnded(pi.getProcessInstanceId());
  }

I do not agree with your last comment.
In case when your case does not work, create jUnit test please.
http://forums.activiti.org/content/sticky-how-write-unit-test


Regards
Martin