I am conducting a small test scenario where I apply a spring component with @EventListener annotations to handle the events that are emitted by the process engine. This way I might have a more generic way to react to those events as opposed to declaring execution listeners in the modeler per activity.
What I notice is that the event listener is invoked twice for the start event of a process; for the end event of a process; and for timer events for both the start and end-events. The values of the DelegationExecution seem to be equal for both invocations. For other activities the start and end events are only invoked once.
Can someone explain why this method is invoked twice for those events? Or could there be some issue in my code setup? I am using a simple spring boot application with embedded process engine and a simple process definition; consisting only of a start event; a script activity that just prints a line to stdout; and and an end event.
for every BPMN-Flowelement the workflow engine throws a start and an end event. Therefore you receive two events when processing one flow element. You need to check the type of the event before execute your logic if you want to avoid double executions.
@Component
public class CustomHistoryEventHandler {
private static final Logger log = LoggerFactory.getLogger(CustomHistoryEventHandler.class);
@EventListener
public void handleEvent(HistoryEvent historyEvent) {
log.info(">>>>>>>> received HistoryEvent: " + historyEvent.getId());
log.info(">>>>>>>> instanceOf: " + historyEvent.getClass().getName());
log.info(">>>>>>>> eventType: " + historyEvent.getEventType() + "\n");
}
}
I understand that upon a transition both a start and an end event are fired. However, in my case with method signature:
@EventListener
public void notify(final DelegateExecution delegateExecution) {
...
}
I receive some notifications twice.
For a start event I get callbacks for start twice. And for the end event I get callbacks for end twice.
To illustrate I share with you my logging output for the tested process; that comprises a start event -> a script task that does nothing -> end event.
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: start
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: start
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: end
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: Start of the process(StartEvent_1) - Event name: take
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: start
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: end
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: First step(Task_16ksokd) - Event name: take
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: start
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: end
> Process instance: c7838280-bd3d-11e9-9703-acde48001122 - Current activity: End of the process(EndEvent_0gil19k) - Event name: end
The process is started by executing runtimeService.startProcessInstanceByKey("…");
For the duplicate entries, the values provided as DelegateExecution are equal; according to the equals method on DelegateExecution.
As you see, the Task behaves as I expect. The start and end process emit duplicate notifications. The same is true for timer events. Those are duplicated as well.
So I understand your answer, but the behavior I encounter is a bit different. I’d expect a start and an end notification (as you described), but I encounter start; then start again and then end. And finally a take transition.
Hope you can help me a bit further with these clarifications.
Furthermore, the class that contains the eventlistener method has a @Component annotation and the bpmn files are in the resources folder of the module that contains the main class for the spring boot packaging plugin. (I use maven.)
Given this setup, everything is loaded and deployed automatically and I do not use a specific binding configuration.
Can you give me some pointers how to implement this binding?
My question was with regard to the BPMN file itself: Does it bind the Handler classes to the events or do you use the @EventListener annotation only?
In the modeler you can define those event handlers on specific flow elements, but of course you should use only one approach…
I was able to reproduce. Currently for start and end events the according Spring Events are obviously generated twice. Truth is, the first start event belongs to the process itself and the last end event as well.
I think you can use the activity instance id to distinguish between these two start respectively end events:
In the case of the process instance event, execution.getActivityInstanceId ().equals(execution.getProcessInstanceId()) should hold. When the start event is executed, the start event has its own activity instance id.