JCR Event Listener in AEM 6.3 | Community
Skip to main content
shahidp
Level 2
March 19, 2019

JCR Event Listener in AEM 6.3

  • March 19, 2019
  • 6 replies
  • 11061 views

I was trying to execute below program in AEM 6.3 which is a example of AEM JCR Event listener , but I did not get desire result.

I have not used

@Reference

     org.apache.sling.jcr.api.SlingRepository repository;

for getting  adminSession instead of this I have used service based admin session.

package com.adobe.aem.community.core.core.listeners;

import java.util.HashMap;

import java.util.Map;

import javax.jcr.Property;

import javax.jcr.RepositoryException;

import javax.jcr.Session;

import javax.jcr.observation.Event;

import javax.jcr.observation.EventListener;

import javax.jcr.observation.ObservationManager;

import org.apache.sling.api.resource.LoginException;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Deactivate;

import org.osgi.service.component.annotations.Modified;

import org.osgi.service.component.annotations.Reference;

import org.osgi.service.metatype.annotations.Designate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.osgi.service.component.ComponentContext;

import javax.jcr.observation.EventIterator ;

@Component(immediate=true,

service= EventListener.class)

public class SimpleResourceListener implements EventListener{

 

    Logger log = LoggerFactory.getLogger(this.getClass());

     private Session adminSession;

     

     

    @Reference

    ResourceResolverFactory resolverFactory;   

   

   

     @Activate

     public void activate(ComponentContext context) throws Exception {

     log.info("activating ExampleObservation");

      Map<String, Object> param = new HashMap<String, Object>();

      param.put(ResourceResolverFactory.SUBSERVICE, "eventwrite");

      ResourceResolver resolver = null;

     try {

         resolver = resolverFactory.getServiceResourceResolver(param);

         adminSession=resolver.adaptTo(Session.class);

         adminSession.getWorkspace().getObservationManager().addEventListener(

          this, //handler

          Event.PROPERTY_ADDED|Event.NODE_ADDED, //binary combination of event types

          "/apps/example", //path

          true, //is Deep?

          null, //uuids filter

          null, //nodetypes filter

          false);

      } catch (RepositoryException e){

      log.error("unable to register session",e);

      throw new Exception(e);

     }

    }

    @Deactivate

    public void deactivate(){

     if (adminSession != null){

      adminSession.logout();

     }

    }

     

    public void onEvent(EventIterator eventIterator) {

      try {

        while (eventIterator.hasNext()){

          log.info("something has been added : {}", eventIterator.nextEvent().getPath());

        }

       } catch(RepositoryException e){

       log.error("Error while treating events",e);

      }

     }

    }

Getting below msg in error log file

[sling-oak-observation-55] org.apache.jackrabbit.oak.jcr.session.RefreshStrategy This session has been idle for 1 minutes and might be out of date. Consider using a fresh session or explicitly refresh the session. java.lang.Exception: The session was created here:

Please help me out.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

6 replies

Gaurav-Behl
Level 10
March 19, 2019

You don't need to close the session here with service users using adaptTo()

Remove this code..

  if (adminSession != null){

      adminSession.logout();

     }

smacdonald2008
Level 10
March 19, 2019

See this article which works fine on 6.4. To convert to AEM 6.3 - use the AEM 6.3 UBER JAR file as opposed to the 6.4 one.

Creating an Event Listener for Adobe Experience Manager 6.4

arunpatidar
Community Advisor
Community Advisor
March 19, 2019

For JCR Event, to get subservice session you have to use slingRepository not ResourceResolverFactory.

adminSession = repository.loginService("datawrite",null);

where datawrite is your subservice mapping.

Please check below article

Creating an Event Listener for Adobe Experience Manager 6.4

Arun Patidar
joerghoh
Adobe Employee
Adobe Employee
March 20, 2019

This message is a bit odd, because it indicates that a session is open for more than 1 minute; but these kind of messages should not appear when you register an ObservationListener to this session. Can you please check that the stacktrace of the warning is matching to the class name of your service?

Next, you get a resourceResolver, expose its internal JCR Session and use it, but at decactivate you only close the session. You should not do that, but instead only close the ResourceResovler you opened.

Level 2
September 12, 2019

Hi,

I am new to AEM. I need a help, I am unable to get resource for a path using event listener in AEM 6.5 . Though the session and resourceResolver are working fine, resource is getting null when i do resourceResolver.getResource(path).

Can someone help me here.

@Activate

     public void activate(ComponentContext context) throws NoSuchElementException,Exception {

     try {

      Map<String, Object> param = new HashMap<String, Object>();

          param.put(ResourceResolverFactory.SUBSERVICE, "writeService");

          resourceResolver = resolverFactory.getServiceResourceResolver(param);

         adminSession=repository.loginService("writeService",null);

         adminSession.getWorkspace().getObservationManager().addEventListener(

          this,Event.PROPERTY_ADDED,"/content/dam",true,null,null,false);

      

          

     } catch (RepositoryException e){

      log.error("unable to register session",e);

      throw new Exception(e);

     }

    }

         

     @Deactivate

     public void deactivate(){

     if (adminSession != null){

    adminSession.logout();

     }

     if(resourceResolver !=null){

     resourceResolver.close();

     }

     }

public void onEvent(EventIterator eventIterator) {

while (eventIterator.hasNext()) {

Event event = eventIterator.nextEvent();

try {

log.info("********INSIDE TRY *****");

Property changedProperty = adminSession.getProperty(event.getPath());

if (changedProperty.getName().equalsIgnoreCase("tiff:imageWidth")

&& !changedProperty.getString().endsWith("!")) {

String metadataPath = changedProperty.getPath().split("/tiff:imageWidth")[0];

log.info("*************Property value: {}", metadataPath + "width >>>>>"+adminSession.getProperty("tiff:imageWidth"));

if (resourceResolver.resolve(metadataPath) != null && resourceResolver.getResource(metadataPath) != null) {

Resource resource = resourceResolver.getResource(metadataPath);

log.info("<<<<<<<<<<<<<<<<<<<<<resource is not null----1!!!>>>>>>>>>>>>>>>>>>>>>>>>>>"+resource.getPath());

if (resource != null) {

log.info("<<<<<<<<<<<<<<<<<<<<<resource is not null-----2!!!>>>>>>>>>>>>>>>>>>>>>>>>>>");

Node metadataNode = resource.adaptTo(Node.class);

log.info("in node object!!");

if (metadataNode.getProperty("tiff:imageWidth").getLong()>2000 || metadataNode.getProperty("tiff:imageLength").getLong()>2000 ) {

metadataNode.setProperty("edam:highResolution", true);

metadataNode.getSession().save();

log.info("Property added successfully!!!!");

}else {

metadataNode.setProperty("edam:highResolution", false);

metadataNode.getSession().save();

log.info("Property added successfully!!!!");

}

}

}

log.info("resource object is null");

break;

}

}

catch (Exception e) {

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

break;

}

}

It is breaking at highlighted condition when resourceResolver.getResource(metadataPath) != null

After splitting the metadatapath value

metadataPath value = /content/dam/<image-name>/jcr:content/metadata

joerghoh
Adobe Employee
Adobe Employee
September 12, 2019

if a resourceResolver.getResource() returns null, the resource is not present (or not visible to the resourceResolver).

Level 2
September 12, 2019

Thanks for the reply Jorg Hoh.

1. Do u mean permissions issue on the content/dam/* folder.

The system user which i created have full permissions.

2. Not available or not present?

How do i confirm that? When verified in crx/de, I am able to see the asset created in that location after uploading.

Level 2
September 13, 2019

Thanks for the update Jorg.

Will try the above solutions and will update.

Level 2
September 13, 2019

The issue seems to be resolved for me today as i did the following change in my code.

  adminSession=repository.loginService("writeService",null);

I am getting the session using loginservice method from repository, i modified it to below

   adminSession = resolver.adaptTo(Session.class);

This worked fine for me, but still not sure if this would be the right solution. I would try the suggestions provided by you and will update here.

joerghoh
Adobe Employee
Adobe Employee
September 16, 2019

This works as well. I saw this approach, but I have not included it into the list above, because you still mix JCR and Sling APIs for reasons not obvious to me. I would still recommend to first option I outlined earlier.

Jörg