Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
BedrockMission!

Learn More

View all

Sign in to view all badges

JCR Event Listener in AEM 6.3

Avatar

Avatar
Validate 1
Level 1
shahidp
Level 1

Likes

3 likes

Total Posts

5 posts

Correct Reply

0 solutions
Top badges earned
Validate 1
Boost 3
Boost 1
View profile

Avatar
Validate 1
Level 1
shahidp
Level 1

Likes

3 likes

Total Posts

5 posts

Correct Reply

0 solutions
Top badges earned
Validate 1
Boost 3
Boost 1
View profile
shahidp
Level 1

19-03-2019

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.

Replies

Avatar

Avatar
Establish
MVP
Gaurav-Behl
MVP

Likes

248 likes

Total Posts

1,147 posts

Correct Reply

283 solutions
Top badges earned
Establish
Give back 300
Give Back 50
Give Back 5
Give Back 3
View profile

Avatar
Establish
MVP
Gaurav-Behl
MVP

Likes

248 likes

Total Posts

1,147 posts

Correct Reply

283 solutions
Top badges earned
Establish
Give back 300
Give Back 50
Give Back 5
Give Back 3
View profile
Gaurav-Behl
MVP

19-03-2019

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

Remove this code..

  if (adminSession != null){

      adminSession.logout();

     }

Avatar

Avatar
Coach
MVP
Arun_Patidar
MVP

Likes

1,345 likes

Total Posts

3,220 posts

Correct Reply

914 solutions
Top badges earned
Coach
Contributor 2
Ignite 10
Give Back 700
Boost 1000
View profile

Avatar
Coach
MVP
Arun_Patidar
MVP

Likes

1,345 likes

Total Posts

3,220 posts

Correct Reply

914 solutions
Top badges earned
Coach
Contributor 2
Ignite 10
Give Back 700
Boost 1000
View profile
Arun_Patidar
MVP

19-03-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

Avatar

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,408 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile

Avatar
Validate 25
Level 10
smacdonald2008
Level 10

Likes

1,408 likes

Total Posts

12,671 posts

Correct Reply

2,278 solutions
Top badges earned
Validate 25
Validate 10
Validate 1
Give back 900
Give back 600
View profile
smacdonald2008
Level 10

19-03-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

Avatar

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile
Jörg_Hoh
Employee

20-03-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.

Avatar

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile
ravi64892
Level 1

12-09-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

Avatar

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile
Jörg_Hoh
Employee

12-09-2019

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

Avatar

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile
ravi64892
Level 1

12-09-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.

Avatar

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile

Avatar
Give Back 5
Level 1
ravi64892
Level 1

Likes

0 likes

Total Posts

9 posts

Correct Reply

0 solutions
Top badges earned
Give Back 5
Give Back 3
Give Back
View profile
ravi64892
Level 1

12-09-2019

Sorry for multiple comments.

I want to share one observation.

Under jcr:content of asset, the parent path is not being updated for sometime. Does that cause a issue. This is happening in my local instance.

Avatar

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile

Avatar
Coach
Employee
Jörg_Hoh
Employee

Likes

1,111 likes

Total Posts

3,145 posts

Correct Reply

1,072 solutions
Top badges earned
Coach
Give back 600
Ignite 5
Ignite 3
Ignite 1
View profile
Jörg_Hoh
Employee

13-09-2019

Well, this is an event listener, which means that the timing is relevant.

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) {

First I would use the API to extract the path of the property (and void the String operation):

String metadataPath = changedProperty.getNode().getPath();

But at that time the path is available in the JCR; but it is not visible to the ResourceResolver. The ResourceResolver is opened during activate, and this means that the JCR session embedded into this ResourceResolver is opened as well. And due to the MVC pattern in Oak this session only sees the state of the repository when it has been opened. Any update in the JCR which is performed outside of this session is not visible.

There are 2 ways to handle this:

* From what I see you can remove the complete ResourceResolver, because I don't see in the logic any case which you cannot handle with the adminSession.. Basically you just use the RR for a few checks and all changes are actually performed on the adminSession.

* Or you add a resourcerResolver.refresh() in front of the check (marked bold).

I would recommend you to use the first option, it will make your code cleaner.

HTH,

Jörg