Why ActivityStartListener is called after the Activity Execution is completed?

I have following simple bpmn xml,

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:flowable="http://flowable.org/bpmn"
             typeLanguage="http://www.w3.org/2001/XMLSchema"
             expressionLanguage="http://www.w3.org/1999/XPath"
             targetNamespace="http://www.flowable.org/processdef">
    <process id="testify" name="testifier" isExecutable="true">
        <startEvent id="start"/>
        <sequenceFlow sourceRef="start" targetRef="task1"/>
        <serviceTask id="task1" name="tasker 1" flowable:async="true" flowable:triggerable="false" flowable:class="ws.flowable.Class1">
        </serviceTask>
        <sequenceFlow sourceRef="task1" targetRef="task2"/>
        <serviceTask id="task2" name="tasker 2" flowable:async="true" flowable:triggerable="false" flowable:class="ws.flowable.Class1">
        </serviceTask>
        <sequenceFlow sourceRef="task2" targetRef="usTask1"/>
        <userTask id="usTask1" flowable:async="true"/>
        <sequenceFlow sourceRef="usTask1" targetRef="end"/>
        <endEvent id="end"/>
    </process>
</definitions>

My execute() method of Java Delegate Class1 looks like,

    public void execute(DelegateExecution execution) {
        //sleeping for 10 secs to learn the behaviour
        Thread.sleep(10000);
    }
  1. I binded an ActivityStartListener to the process engine for the FlowableEngineEventType = ACTIVITY_STARTED
  2. When I triggered the process, why did my ActivityStartListener executed after execute() method is finished for serviceTask with id = task1? Same happened for task2 as well. Only after 10 secs , ActivityStartListener onEvent() method is called.

By the way, My Flowable ProcessEngine creation looks like,

ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setDataSource(dataSource);
        cfg.setAsyncExecutorActivate(true);
        ((ProcessEngineConfigurationImpl) cfg).setActivityBehaviorFactory(new DefaultActivityBehaviorFactory(classDelegateFactory));
ProcessEngine engine = cfg.buildProcessEngine();

ActivityStartListener activityStartListener = new ActivityStartListener();
engine.getRuntimeService().addEventListener(activityStartListener, ACTIVITY_STARTED);
return engine;

ActivityStartListener should be called before calling execute() method right?

Any update here team?

That’s very weird, looking into the code that event is fired before the execute(): https://github.com/flowable/flowable-engine/blob/master/modules/flowable-engine/src/main/java/org/flowable/engine/impl/agenda/ContinueProcessOperation.java#L265

Did you verify the activity ids? What data is in the events you’re receiving?

Please don’t bump posts like this. This is an open source forum, people that respond here do it often on a voluntary basis.

@joram I did verify the activityId’s and ActivityStartedListener executed after JavaDelegate.execute() was completed.

Also, to answer your question “Did you verify the activity ids”? I have added some print statements and generated logs to describe the behaviour.

My Java delegate class looks like,

class Class1 {
    public void execute(DelegateExecution execution) {
        //sleeping for 10 secs to learn the behaviour
        Thread.sleep(10000);
        System.out.println("Inside Delegate class: " + execution.getCurrentActivityId());
    }
}

and my ActivityStartListener looks like,

public class ActivityStartListener implements FlowableEventListener {

    @Override
    public void onEvent(FlowableEvent event) {
        FlowableActivityEventImpl activity = (FlowableActivityEventImpl) event;
        System.out.println("Inside ActivityStartListener: "activity.getActivityId());
    }

    @Override
    public boolean isFailOnException() {
        return true;
    }

    @Override
    public boolean isFireOnTransactionLifecycleEvent() {
        return true;
    }

    @Override
    public String getOnTransaction() {
        return "COMMITTED";
    }
}

When I executed bpmn flow,
I got the logs in following order,

Inside ActivityStartListener: start
Inside Delegate class: task1
Inside ActivityStartListener: task1
Inside Delegate class: task2
Inside ActivityStartListener: task2
Inside ActivityStartListener: usTask1

From above logs (line 2,3), you can see it reached delegate class and then only to start listener.

flowable pom.xml used = 6.4.1

Please let me know what’s the reason behind this behaviour.

I checked the code flow, dispatchEvent doesn’t fires the event. Finally somewhere it added the event in a map and ended. Reference: (flowable-engine/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/event/FlowableEventSupport.java at main · flowable/flowable-engine · GitHub). I think it must have fired after the execute() was completed.

This is solved by overriding isFireOnTransactionLifecycleEvent() and returning “false” of the listener class.