Event Listener Module


Confluence 1.4 and later


In Confluence 3.3 and later, Confluence events are annotation-based. This means that you have two options when writing event listeners. Option 1 is the Event Listener plugin module, using the com.atlassian.event.EventListener class. Option 2 is to declare your listener as a component and use annotation-based event listeners, annotating your methods to be called for specific event types. The component will need to register itself at the time it gets access to the EventPublisher, typically in the constructor. More information and examples are below.

Every time something important happens within Confluence (a page is added or modified, the configuration is changed, etc.), an 'event' is triggered. Listeners allow you to extend Confluence by installing code that responds to those events.

Plugin Events

It is possible to listen for plugin install/uninstall/enable/disable events, however this will be unreliable when trying to listen for events about your own plugin. You will not receive a PluginDisableEvent or PluginUninstallEvent for the plugin itself. To trigger actions for these events, one (or more) of your modules (macro, event listener, etc.) should implement the Making your Plugin Modules State Aware interface instead.

Synchronous Events

Confluence events are currently processed synchronously. That is, Confluence will wait for your event to finish processing before returning from the method that was the source of the event. This makes it very important that any event listener you write completes as quickly as possible.

Adding a Listener Plugin

Listeners are a kind of Confluence plugin module.

Option 1. Annotation Based Event Listeners

Events 2.0

From Confluence 3.3 you can take advantage of annotation-based event listeners.

Using annotation-based event listeners allows you to annotate methods to be called for specific event types. The annotated methods must take a single parameter specifying the type of event that should trigger the method.

You must also register the class with the EventPublisher, which can be injected to the listener.

(info) As an annotation-based event listener is not required to implement the com.atlassian.event.EventListener interface, you cannot use the listener module descriptor.

In order to use the annotation-based event listeners you must register your listener as a component. For example:

<atlassian-plugin key="listenerExample" name="Listener Examples" plugins-version="2">
        <vendor name="${project.organization.name}" url="${project.organization.url}" />

    <component name="Annotated Event Listener" class="com.atlassian.confluence.plugin.example.listener.AnnotatedListener" key="annotatedListener"/>


See the example code for how to implement this listener: Annotation Based Event Listener Example

Option 2. The Listener Plugin Module

The Listener Plugin XML

Each listener is a plugin module of type 'listener', packaged with whatever Java classes and other resources the listener requires in order to run. Here is an example atlassian-plugin.xml file containing a single listener:

<atlassian-plugin name='Optional Listeners' key='confluence.extra.auditor'>
        <description>Audit Logging</description>
        <vendor name="Atlassian Software Systems" url="http://www.atlassian.com"/>

    <listener name='Audit Log Listener' class='com.example.listener.AuditListener'
        <description>Provides an audit log for each event within Confluence.</description>

The listener module definition has no configuration requirements beyond any other module: just give it a name, a key, and provide the name of the class that implements the listener.

The Listener Class

The class attribute of the listener module definition must refer to a Java class that implements the com.atlassian.confluence.event.EventListener interface. This is the interface:

package com.atlassian.confluence.event;

import com.atlassian.confluence.event.events.ConfluenceEvent;

 * Defines a listener for Confluence events.
public interface EventListener
     * Perform some action as a response to a Confluence event. The EventManager will
     * ensure that this is only called if the class of the event matches one of the
     * classes returned by getHandledEventClasses
     * @param event some event triggered within Confluence
    void handleEvent(ConfluenceEvent event);

     * Determine which event classes this listener is interested in.
     * The EventManager performs rudimentary filtering of events by their class. If
     * you want to receive only a subset of events passing through the system, return
     * an array of the Classes you wish to listen for from this method.
     * For the sake of efficiency, only exact class matches are performed. Sub/superclassing
     * is not taken into account.
     * Returning an empty array will allow you to receive every event.
     * @return An array of the event classes that this event listener is interested in,
     *         or an empty array if the listener should receive all events. <b>Must not</b>
     *         return null.
    Class[] getHandledEventClasses();

A more detailed example, with sample code, can be found in Writing an Event Listener Plugin Module.

Events and Event Types

All events within Confluence extend from com.atlassian.com.event.events.ConfluenceEvent. In general, we use the following convention for naming each type of ConfluenceEvent:


For example, we have the following event types relating to space events: SpaceCreateEvent, SpaceUpdateEvent, SpaceRemoveEvent. In the above description space would correspond to <Object> and create, update, or remove would correspond to <Operation>.

Occasionally, an operation is so singular that its meaning will be obvious without use of this naming convention; for example a LoginEvent or ConfigurationEvent.

Limitations of Events
  • Events are a notification that something has occurred. The event system is not designed to allow a listener to veto the action that caused the event.
  • There is no loop detection. If you write a listener for the SpaceModifiedEvent that itself causes a SpaceModifiedEvent to be generated, you are responsible for preventing the ensuing infinite loop.
Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport