AEM 6.5 EventHandler Not Triggering on Page Deletion | Community
Skip to main content
Level 2
May 26, 2025
Solved

AEM 6.5 EventHandler Not Triggering on Page Deletion

  • May 26, 2025
  • 2 replies
  • 552 views

Hi Everyone,

I am currently working on Adobe Experience Manager 6.5.17 and implementing a custom EventHandler to listen for page deletion events using the PageEvent.EVENT_TOPIC.

Here’s a snippet of my code:

@8220494(
service = EventHandler.class,
immediate = true,
property = {
EventConstants.EVENT_TOPIC + "=" + PageEvent.EVENT_TOPIC
}
)
public class PageDeletionEventHandler implements EventHandler {

private static final Logger LOG = LoggerFactory.getLogger(PageDeletionEventHandler.class);

@9944223
public void handleEvent(Event event) {
LOG.info("Received event: {}", event.getTopic());
PageEvent pageEvent = PageEvent.fromEvent(event);
for (PageModification mod : pageEvent.getModifications()) {
if (mod.getType() == PageModification.ModificationType.DELETED) {
LOG.info("Page deleted at path: {}", mod.getPath());
}
}
}
}

 

The handleEvent method is triggered correctly for CREATED and MODIFIED events - but not for DELETED events when I delete pages via the AEM Sites console.

The bundle is active, the component is registered, and logging works for other event types.

Has anyone faced this issue?

Best answer by SantoshSai

Hi @navyavo,

Some page deletion actions in the Sites console are processed through JCR-level operations or as part of workflows, which sometimes prevents the PageEvent system from reliably catching the DELETED event.

Can you can try using a javax.jcr.observation.EventListener to listen for NODE_REMOVED:

@Activate
protected void activate() throws RepositoryException {
    Session session = repository.loginService("datawrite", null);
    ObservationManager observationManager = session.getWorkspace().getObservationManager();
    observationManager.addEventListener(
        this,
        Event.NODE_REMOVED,
        "/content",
        true,
        null,
        null,
        false
    );
}

This allows more fine-grained listening at the JCR level, especially for deletion operations.

Or


If you’re looking for publish-side deletion (deactivation) tracking, try ReplicationAction.EVENT_TOPIC instead:

@Component(
    service = EventHandler.class,
    immediate = true,
    property = {
        EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC
    }
)
public class PageReplicationEventHandler implements EventHandler {

    private static final Logger LOG = LoggerFactory.getLogger(PageReplicationEventHandler.class);

    @Override
    public void handleEvent(Event event) {
        ReplicationAction action = ReplicationAction.fromEvent(event);
        if (ReplicationActionType.DEACTIVATE.equals(action.getType())) {
            LOG.info("Page deactivated: {}", action.getPath());
        }
    }
}

 Reference: https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/aem-eventing/overview

Hope this helps!

2 replies

SantoshSai
Community Advisor
SantoshSaiCommunity AdvisorAccepted solution
Community Advisor
May 26, 2025

Hi @navyavo,

Some page deletion actions in the Sites console are processed through JCR-level operations or as part of workflows, which sometimes prevents the PageEvent system from reliably catching the DELETED event.

Can you can try using a javax.jcr.observation.EventListener to listen for NODE_REMOVED:

@Activate
protected void activate() throws RepositoryException {
    Session session = repository.loginService("datawrite", null);
    ObservationManager observationManager = session.getWorkspace().getObservationManager();
    observationManager.addEventListener(
        this,
        Event.NODE_REMOVED,
        "/content",
        true,
        null,
        null,
        false
    );
}

This allows more fine-grained listening at the JCR level, especially for deletion operations.

Or


If you’re looking for publish-side deletion (deactivation) tracking, try ReplicationAction.EVENT_TOPIC instead:

@Component(
    service = EventHandler.class,
    immediate = true,
    property = {
        EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC
    }
)
public class PageReplicationEventHandler implements EventHandler {

    private static final Logger LOG = LoggerFactory.getLogger(PageReplicationEventHandler.class);

    @Override
    public void handleEvent(Event event) {
        ReplicationAction action = ReplicationAction.fromEvent(event);
        if (ReplicationActionType.DEACTIVATE.equals(action.getType())) {
            LOG.info("Page deactivated: {}", action.getPath());
        }
    }
}

 Reference: https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/aem-eventing/overview

Hope this helps!

Santosh Sai
kautuk_sahni
Community Manager
Community Manager
July 31, 2025

@navyavo Did you find the suggestions helpful? If you need more information, please let us know. If a response resolved your issue, kindly mark it as correct to help others in the future. Alternatively, if you discovered a solution on your own, we'd appreciate it if you could share it with the community. Thank you !

Kautuk Sahni
AmitVishwakarma
Community Advisor
Community Advisor
May 27, 2025

Hi @navyavo ,

Try below solution:

To reliably detect page deletions, listen for JCR NODE_REMOVED events under /content.

JCR EventListener Implementation

@Component(immediate = true, service = EventListener.class) public class PageDeletionJcrEventListener implements EventListener { private static final Logger LOG = LoggerFactory.getLogger(PageDeletionJcrEventListener.class); @Reference private SlingRepository repository; private Session session; @Activate protected void activate() throws Exception { session = repository.loginService("datawrite", null); Workspace workspace = session.getWorkspace(); ObservationManager observationManager = workspace.getObservationManager(); observationManager.addEventListener( this, Event.NODE_REMOVED, "/content", true, null, null, false ); LOG.info("JCR EventListener registered for NODE_REMOVED under /content"); } @Deactivate protected void deactivate() { if (session != null && session.isLive()) { session.logout(); } } @Override public void onEvent(EventIterator events) { while (events.hasNext()) { Event event = events.nextEvent(); try { String path = event.getPath(); LOG.info("Node removed at path: {}", path); } catch (RepositoryException e) { LOG.error("Error handling node removed event", e); } } } }

Service User Mapping (Mandatory for loginService)

Make sure you have a system user (datawrite) with read access under /content and register a mapping in org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended:

your.bundle.symbolic.name:datawrite=datawrite-service-user

And ensure this user has read access to /content, or use jcr:read permission via an ACL.

 

Also Track Deactivation (Replication)

To track page deactivations, use:

@component( service = EventHandler.class, immediate = true, property = { EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC } ) public class PageReplicationEventHandler implements EventHandler { private static final Logger LOG = LoggerFactory.getLogger(PageReplicationEventHandler.class); @Override public void handleEvent(Event event) { ReplicationAction action = ReplicationAction.fromEvent(event); if (ReplicationActionType.DEACTIVATE.equals(action.getType())) { LOG.info("Page deactivated: {}", action.getPath()); } } }