AEM Preprocessor

AEM provides different ways to listen to multiple events at the code level. There can be scenarios where you may want to activate/deactivate a page and based on the status of this event, you want to trigger any other flow of actions such as:

  • Sending an email
  • Invalidating the dispatcher cache
  • Disconnecting the user sessions, or
  • Re-indexing of the repository on successful activation/deactivation, etc.


You can further trigger the activation/deactivation itself based on any prior action/event. When such situations are considered, you may want to be sure if the prior event completed successfully or not and based on the status, you may want to revert to the previous state of the page and defer the action of page activation/deactivation.

AEM can provide various ways of achieving the above scenarios. You have options such as:

  1. Activation/Deactivation workflows.
  2. Event Listeners/Event Handlers
  3. Pre-processors.


Let’s discuss the pros and cons of the first 2 ways of listening to the events.


Workflows can be configured as launchers. Once any pre-configured property or node is changed, deleted or created, you can trigger this launcher to perform activation of the page. However, this may require a user intervention to approve the content and publish that. Also, if something goes wrong with payload publication, the failure message cannot be pushed back to the author’s inbox. And that way, the author will never be able to understand what failed and either he will forcefully publish the page or will stop it completely, without knowing the root cause of the failure.

Event Listeners:

Event listeners are fired when any intended event occurs in the repository. Based on the event type, the required action can further be triggered. However, in case of any failure just before the activation, an event listener may still allow the page to get activated. Such as just before the actual activation, if the DB connection fails, or any required indexing doesn’t take place, the activation should be stopped. But event listener will not be able to stop the activation/deactivation at that point.


Here comes the pre-processor to the rescue. Pre-processors are invoked just before the activation/deactivation. If any error or failure occurs just before the activation, you can catch that and throw your custom error message. Throwing an exception in the preprocessor’s overridden method will stop the activation/deactivation.

Thus while using a preprocessor, there is no longer a need to assign ACLs to the authors or creating any user groups or creation of the workflow launchers. As the preprocessors run just before every activation/deactivation, they can provide the actual error message. Based on the error message, appropriate actions can be taken by the content authors.

Code Snippet for Pre-processor:


public void preprocess(final ReplicationAction replicationAction, final ReplicationOptions replicationOptions)

throws ReplicationException {

    String actionPath = replicationAction.getPath(); //Get the action path

    String action = replicationAction.getType().getName(); //Get the action type name e.g. activate/deactivate

    Session session = null;

    String activatedPage = "";

    try {

        resolver = getResourceResolver(resolverFactory);

        if (resolver != null) {

            session = resolver.adaptTo(Session.class);

            if ( /*Some condition*/ ) {

                Resource resource = resolver.getResource(actionPath);

                if (resource.adaptTo(ModifiableValueMap.class).get("jcr:primaryType")

                    .toString().equals("cq:Page")) {

                    if (action.equalsIgnoreCase("Activate")) {

                        // Your custom code on activation

                    } else if (action.equalsIgnoreCase("Deactivate")) {

                        // Your custom code on deactivation




        } else {

  "Resource is null");


    } catch (LoginException | RepositoryException | SQLException e) {

        log.error(e.getMessage(), e);

        throw new ReplicationException(e);

    } finally {

        if (session != null && session.isLive()) {


            /*session = null;*/






About The Author