Hi All,
the following code for onChange used to work in AEM 6.2 but after we migrated to 6.3 , I see onChange is not getting fired, not sure what is going wrong.
@Component(immediate = true)
@Service
@Properties(value = { @Property(name = ResourceChangeListener.PATHS, value = { CommunityConstants.CONTENT_ROOT_PATH }),
@Property(name = ResourceChangeListener.CHANGES, value = { "ADDED", "CHANGED" }, propertyPrivate = true) })
public class xyz implements ResourceChangeListener {
@Reference
private ResourceResolverFactory resourceResolverFactory;
@Reference
private ContentModelService contentModelService;
@Override
public void onChange(@Nonnull List<ResourceChange> changes) {
//some logic here
}
}
Please help me to understand it further.
Many Thanks,
Kranthi
Some basic checks first:
* Please check that the bundle containing this service is active.
* Please check that the component "xyz" is active (check on the Components list in the OSGI webconsole).
Jörg
Issue is how session is obtained. You need to use a system user and give correct permissions. This works....
Component (immediate= true ,
|
@Activate to get the session & @Deactivate to destroy the session ?
package com.xyz.help.conteenginecore.listener;
import java.util.List;
import java.util.Optional;
import com.adobe.cq.social.community.api.CommunityConstants;
import com.xyz.help.conteenginecore.Constants;
import com.xyz.help.conteenginecore.ContentModel;
import com.xyz.help.conteenginecore.ContentModelService;
import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nonnull;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Listens changing of resources, and in case when was added "articelNo"
* property, adding generated "articleId" property to the same node.
*/
@Component(immediate = true)
@Service
@Properties(value = { @Property(name = ResourceChangeListener.PATHS, value = { CommunityConstants.CONTENT_ROOT_PATH }),
@Property(name = ResourceChangeListener.CHANGES, value = { "ADDED", "CHANGED" }, propertyPrivate = true) })
public class GenerateArticleIdOnAddingArticleNumber implements ResourceChangeListener {
private static final Logger LOG = LoggerFactory.getLogger(GenerateArticleIdOnAddingArticleNumber.class);
@Reference
private ResourceResolverFactory resourceResolverFactory;
@Reference
private ContentModelService contentModelService;
@Override
public void onChange(@Nonnull List<ResourceChange> changes) {
try (ResourceResolver resolver = resourceResolverFactory
.getServiceResourceResolver(Constants.CONTENT_ENGINE_AUTH_INFO)) {
changes.stream().filter(resourceChange -> resourceChange.getAddedPropertyNames() != null)
.filter(resourceChange -> !resourceChange.getAddedPropertyNames().isEmpty())
.filter(resourceChange -> resourceChange.getAddedPropertyNames()
.contains(ContentModel.HelpArticle.PN_ARTICLE_NUMBER))
.forEach(resourceChange -> {
addArticleIdProperty(resourceChange, resolver);
addDefClassificationProperty(resourceChange, resolver);
});
resolver.commit();
} catch (LoginException e) {
LOG.error("Can't perform action", e);
} catch (PersistenceException e) {
LOG.error("Can't perform action", e);
}
}
private void addArticleIdProperty(ResourceChange resourceChange, ResourceResolver resourceResolver) {
Resource resource = resourceResolver.resolve(resourceChange.getPath());
Optional.ofNullable(resource.adaptTo(ModifiableValueMap.class)).ifPresent(valueMap -> valueMap
.put(ContentModel.HelpArticle.PN_ARTICLE_ID, contentModelService.generateArticleId(resource)));
}
private void addDefClassificationProperty(ResourceChange resourceChange, ResourceResolver resourceResolver) {
Resource resource = resourceResolver.resolve(resourceChange.getPath());
Optional.ofNullable(resource.adaptTo(ModifiableValueMap.class)).ifPresent(
valueMap -> valueMap.put(ContentModel.HelpArticle.PN_CLASSIFICATION, "ArticleClassification:help"));
}
@VisibleForTesting
void bindResourceResolverFactory(ResourceResolverFactory resolverFactory) {
this.resourceResolverFactory = resolverFactory;
}
@VisibleForTesting
void bindContentModelService(ContentModelService contentModelService) {
this.contentModelService = contentModelService;
}
}
Views
Replies
Total Likes
when I install the bundle, I see null pointer exception
24.04.2019 09:49:34.993 *INFO* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber activating ExampleObservation
24.04.2019 09:49:35.162 *ERROR* [FelixDispatchQueue] org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerException)
Views
Replies
Total Likes
An exception in the activate() method renders this component unavailable.
Views
Replies
Total Likes
To get an EVENT Handler working on 6.3 - follow this article - see how we created a System user and SLing Mapping.
Creating an Event Listener for Adobe Experience Manager 6.4
You will need to use a 6.3 UBER JAR file - not the 6.4 one in that article.
The application logic that article does result in an Event firing.
Hope this helps.
OH yeah - for an AEM 6.3 project and UBER 6.3 JAR - see:
Creating an Adobe Experience Manager 6.3 Project using Adobe Maven Archetype 12
Views
Replies
Total Likes
smacdonald2008, yes we are using 6.3 Uber JAR file. onChange event is getting triggerd but I see problem in getting the ResourceResolver
I created the system user too
now write a method to get the resolver
public static final String CONTENT_ENGINE_SERVICE = "systemUser";
@Reference
private ResourceResolverFactory resourceResolverFactory;
private ResourceResolver getResourceResolver() {
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, CONTENT_ENGINE_SERVICE);
ResourceResolver resolver = null;
try {
resolver = resolverFactory.getServiceResourceResolver(param);
} catch (Exception e) {
LOG.error("Exception", e);
}
return resolver;
}
but I am not getting the ResourceResolver. not sure what is going wrong.
when I install the bundle, I see the following error in the error.log file
1. bind method [bindResolverFactory] not found; Component will fail
2. org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerException)
25.04.2019 05:58:40.625 *ERROR* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.content-engine-core-bundle [ com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber(3787)] bind method [bindResolverFactory] not found; Component will fail
25.04.2019 05:58:40.625 *ERROR* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.content-engine-core-bundle [ com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber(3787)] bind method [bindResolverFactory] not found
25.04.2019 05:58:41.621 *ERROR* [FelixDispatchQueue] org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerExcepti on)
java.lang.NullPointerException: null
Views
Replies
Total Likes
Can you share your Apache Sling Service User Mapper service configuration:
It should be in below format because in point 4 above you shared is not correct format
Correct Format is below:
service-name:[sub-service-name]=system-user |
Service-name: The service-name is the symbolic name of the bundle providing the service.
Sub-Service-Name:A Service may be comprised of multiple parts, so each part of the service may be further identified by a Subservice Name. This field is optional.
com.demo.aem:dataService=dataUser
I still see org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerException) in error.log file.
here is my Apache Sling Service User Mapper Service
com.xyz.help.content-engine-core-bundle:vulpe=vulpe
here vulpe is the system user
Views
Replies
Total Likes
in my code, this statement is returning null , I mean I am not getting ResourceResolver object
resolverFactory.getServiceResourceResolver(param)
Views
Replies
Total Likes
typically you don't need the "bind*" methods at all, if you just want to have simple injection. But the problem in your case seems to be the "@VisibleForTesting" annotation, which makes this method visible for the scr plugin at buildtime, but hides it during runtime. Removing this annotation will likely make your problem go away, but it might have other impact.
Jörg
Hi Joerg Hoh, yes bundle & component both are active but still onChange event is not getting triggered in AEM 6.3 , but it works fine in AEM 6.2.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies