[id='event-listeners-con_{context}']
= Event Listeners in the {PROCESS_ENGINE}

You can develop a class that implements the `ProcessEventListener` interface. This class can listen to process-related events, such as starting or completing a process or entering and leaving a node.

The {PROCESS_ENGINE} passes an event object to this class. The object provides access to related information, like the process instance and node instance linked to the event.

The following list shows the different methods of the `ProcessEventListener` interface:

.Methods of the `ProcessEventListener` interface
[source,java]
----
public interface ProcessEventListener {

  void beforeProcessStarted( ProcessStartedEvent event );
  void afterProcessStarted( ProcessStartedEvent event );
  void beforeProcessCompleted( ProcessCompletedEvent event );
  void afterProcessCompleted( ProcessCompletedEvent event );
  void beforeNodeTriggered( ProcessNodeTriggeredEvent event );
  void afterNodeTriggered( ProcessNodeTriggeredEvent event );
  void beforeNodeLeft( ProcessNodeLeftEvent event );
  void afterNodeLeft( ProcessNodeLeftEvent event );
  void beforeVariableChanged(ProcessVariableChangedEvent event);
  void afterVariableChanged(ProcessVariableChangedEvent event);

}
----

The `before` and `after` event calls typically act like a stack. If event A directly causes event B, the following sequence of calls happens:

* Before A
* Before B
* After B
* After A

For example, if leaving node X triggers node Y, all event calls related to triggering node Y occur between the `beforeNodeLeft` and `afterNodeLeft` calls for node X. 

In the same way, if starting a process directly causes some nodes to start, all `nodeTriggered` and `nodeLeft` event calls occur between the `beforeProcessStarted` and `afterProcessStarted` calls.

This approach reflects cause and effect relationships between events. However, the timing and order of `after` event calls are not always intuitive. For example, an `afterProcessStarted` call can happen after the `afterNodeLeft` calls for some nodes in the process.

In general, to be notified when a particular event occurs, use the `before` call for the event. Use an `after` call only if you want to make sure that all processing related to this event has ended, for example, when you want to be notified when all steps associated with starting a particular process instance have been completed.

Depending on the type of node, some nodes might only generate `nodeLeft` calls and others might only generate `nodeTriggered` calls. For example, catch intermediate event nodes do not generate `nodeTriggered` calls, because they are not triggered by another process node. Similarly, throw intermediate event nodes do not generate `nodeLeft` calls, as these nodes do not have an outgoing connection to another node.

The `KieSession` class implements the `RuleRuntimeEventManager` interface that provides methods for registering, removing, and listing event listeners, as shown in the following list.

.Methods of the `RuleRuntimeEventManager` interface
[source,java,subs="attributes+"]
----
    void addEventListener(AgendaEventListener listener);       
    void addEventListener(RuleRuntimeEventListener listener);       
    void removeEventListener(AgendaEventListener listener);    
    void removeEventListener(RuleRuntimeEventListener listener);    
    Collection<AgendaEventListener>	getAgendaEventListeners(); 
    Collection<RuleRuntimeEventListener> getRuleRintimeEventListeners(); 
----

However, in a typical case, do not use these methods. 

If you are using the `RuntimeManager` interface, you can use the `RuntimeEnvironment` class to register event listeners.

If you are using the Services API, you can add fully qualified class names of event listeners to the `META-INF/services/org.jbpm.services.task.deadlines.NotificationListener` file in your project. The Services API also registers some default listeners, including `org.jbpm.services.task.deadlines.notifications.impl.email.EmailNotificationListener`, which can send email notifications for events.

To exclude a default listener, you can add the fully qualified name of the listener to the `org.kie.jbpm.notification_listeners.exclude` JVM system property.
