Scheduler unable to trigger in AEM author instance | Community
Skip to main content
Anny0505
New Participant
January 20, 2022
Solved

Scheduler unable to trigger in AEM author instance

  • January 20, 2022
  • 3 replies
  • 7130 views

Hi All,

 

I have scheduler configured in AEM to perform some activity everyday night at 2pm. My scheduler every 3 to 4 days it is unable to trigger job and do not log any information in the logs. I'm using AEM 6.5 and with latest service pack. 

Please help or provide troubleshooting steps.

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

First I would like to ask few questions here -

 

1. Are you facing this issue since long time ?

2. Have you written this scheduler with OSGi R6 annotation?

3. Have you made any changes in scheduler recently and deploys the same without modifying the cronjob expression?

 

I had similar experience with scheduler and able to fix the issue.

 

 

Sharing my demo scheduler and Implementation class as reference , please review code comments and I believe it will help you to debug the issue -

 

Scheduler -

 

/**
*
*/
package com.aem.demo.core.schedulers;

import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
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 com.aem.demo.core.configurations.TaskNotificationSchedulerConfiguration;
import com.aem.demo.core.services.TaskNotificationService;
import com.google.common.base.Strings;

/**
* @380 debal
*
* A cron-job like tasks that get executed regularly.
*/
@8220494(service = Runnable.class, immediate = true)
@Designate(ocd = TaskNotificationSchedulerConfiguration.class)
public class TaskNotificationScheduler implements Runnable {

private final Logger logger = LoggerFactory.getLogger(TaskNotificationScheduler.class);

@3214626
TaskNotificationService taskNotificationService;

@3214626
Scheduler scheduler;

private String contentDampath;
private String schedulerName;

@580286
private void activate(TaskNotificationSchedulerConfiguration configguration) {

this.contentDampath = configguration.assetPath();
this.schedulerName = configguration.schdulerName();
logger.info("**** Task Notification Scheduler ****");
//This scheduler will continue to run automatically even after the server reboot, otherwise the scheduled tasks will stop running after the server reboot.
addScheduler(configguration);
}

@9182423
protected void modified(TaskNotificationSchedulerConfiguration configguration) {
// Remove the scheduler registered with old configuration
removeScheduler(configguration);

contentDampath = configguration.assetPath();
// Add the scheduler registered with new configuration
addScheduler(configguration);

}

private void addScheduler(TaskNotificationSchedulerConfiguration configguration) {

boolean enabled = configguration.enabled();
if (enabled) {
ScheduleOptions scheduleOptions = scheduler.EXPR(configguration.cronExpression());

if (!Strings.isNullOrEmpty(schedulerName)) {
scheduleOptions.name(schedulerName);
scheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, scheduleOptions);
logger.info("****** Task Notification Scheduler has been added successfully ******");

}

} else {
logger.info("****** Task Notification Scheduler is in disable state ******");
}

}

@3038739
protected void deactivated(TaskNotificationSchedulerConfiguration configguration) {
logger.info("**** Removing Task Notification Scheduler Successfully on deactivation ****");
removeScheduler(configguration);
}

private void removeScheduler(TaskNotificationSchedulerConfiguration configguration) {

logger.info("**** Removing Task Notification Scheduler Successfully **** {}", schedulerName);
scheduler.unschedule(schedulerName);

}

@9944223
public void run() {
taskNotificationService.setTaskNotification(contentDampath);
logger.info("******Inside Task Notification Scheduler ******");

}

}

 

 

Impl -

 

/**
*
*/
package com.aem.demo.core.services.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ModifiableValueMap;
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.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.granite.taskmanagement.Task;
import com.adobe.granite.taskmanagement.TaskManager;
import com.adobe.granite.taskmanagement.TaskManagerException;
import com.adobe.granite.taskmanagement.TaskManagerFactory;
import com.adobe.granite.workflow.exec.InboxItem;
import com.aem.demo.core.services.TaskNotificationService;
import com.drew.lang.annotations.Nullable;
import com.google.common.base.Strings;

/**
* @380 debal
*
* This Implementation class is responsible to responsible to set/send
* notification in AEM inbox in case we set expiration datetime of an
* asset after current date time. Task Management in AEM is the set of
* APIs that manage Tasks, which can show up in AEM user's inbox. This
* can be done using Task and TaskManager API
*/
@8220494(service = TaskNotificationService.class, immediate = true)
public class TaskNotificationServiceImpl implements TaskNotificationService {

private final Logger logger = LoggerFactory.getLogger(TaskNotificationServiceImpl.class);

public static final String NOTIFICATION_TASK_TYPE = "Notification";

@3214626
ResourceResolverFactory resourceResolverFactory;

@9944223
public void setTaskNotification(String assetPath) {

ResourceResolver serviceResourceResolver = getResourceResolver();

try {

TaskManager taskManager = serviceResourceResolver.adaptTo(TaskManager.class);
TaskManagerFactory taskManagerFactory = taskManager.getTaskManagerFactory();
if (!Strings.isNullOrEmpty(assetPath)) {
Resource resource = serviceResourceResolver.getResource(assetPath);
if (Objects.nonNull(resource) && resource.isResourceType("dam:Asset")) {
Resource metadataresource = resource.getChild("jcr:content/metadata");
ModifiableValueMap modifiableValueMap = metadataresource.adaptTo(ModifiableValueMap.class);

@3146596
String creatorName = modifiableValueMap.get("dc:creator", String.class);

@3146596
Date expirydate = modifiableValueMap.get("prism:expirationDate", Date.class);
logger.info("*** Expiration Date ***{}", expirydate);

Date currentDate = new Date();
if (Objects.nonNull(expirydate) && !Strings.isNullOrEmpty(creatorName)) {
if (expirydate.after(currentDate)) {
Task newTask = taskManagerFactory.newTask(NOTIFICATION_TASK_TYPE);
newTask.setName("Content Expiry Notification");
newTask.setContentPath(assetPath);
// Optionally set priority (High, Medium, Low)
newTask.setPriority(InboxItem.Priority.HIGH);
newTask.setDescription("Content Expiry Notification");
newTask.setInstructions("Content Expiry Notification");
newTask.setCurrentAssignee(creatorName);
taskManager.createTask(newTask);

}

}

}

}

} catch (TaskManagerException te) {
logger.error("Could not create task {} ", te.getMessage());
} finally {
if (Objects.nonNull(serviceResourceResolver)) {
serviceResourceResolver.close();
}

}
}

private ResourceResolver getResourceResolver() {
Map<String, Object> map = new HashMap<String, Object>();
map.put(resourceResolverFactory.SUBSERVICE, "readWriteService");
ResourceResolver serviceResourceResolver = null;
try {

serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(map);
} catch (LoginException e) {
logger.error("Could not get service user [ {} ]", "demoSystemUser", e.getMessage());
}
return serviceResourceResolver;

}

}

 

Interface -

 

/**
*
*/
package com.aem.demo.core.services;

/**
* @380 debal
*
* This service is responsible to set/send notification in AEM inbox
*/
public interface TaskNotificationService {

public void setTaskNotification(String assetPath);
}

 

 

Please review the comments at code level.

3 replies

joerghoh
Employee
January 20, 2022

Another possible problem is that the threadpool you are using (most likely the default thread pool) does not have a free thread to run your job.

DEBAL_DAS
New Participant
October 1, 2022

@joerghoh 

Are you referring Apache Sling Job Thread Pool OSGi configuration here? Please correct me.

 

joerghoh
Employee
October 3, 2022

yes

DEBAL_DAS
DEBAL_DASAccepted solution
New Participant
January 20, 2022

First I would like to ask few questions here -

 

1. Are you facing this issue since long time ?

2. Have you written this scheduler with OSGi R6 annotation?

3. Have you made any changes in scheduler recently and deploys the same without modifying the cronjob expression?

 

I had similar experience with scheduler and able to fix the issue.

 

 

Sharing my demo scheduler and Implementation class as reference , please review code comments and I believe it will help you to debug the issue -

 

Scheduler -

 

/**
*
*/
package com.aem.demo.core.schedulers;

import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
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 com.aem.demo.core.configurations.TaskNotificationSchedulerConfiguration;
import com.aem.demo.core.services.TaskNotificationService;
import com.google.common.base.Strings;

/**
* @380 debal
*
* A cron-job like tasks that get executed regularly.
*/
@8220494(service = Runnable.class, immediate = true)
@Designate(ocd = TaskNotificationSchedulerConfiguration.class)
public class TaskNotificationScheduler implements Runnable {

private final Logger logger = LoggerFactory.getLogger(TaskNotificationScheduler.class);

@3214626
TaskNotificationService taskNotificationService;

@3214626
Scheduler scheduler;

private String contentDampath;
private String schedulerName;

@580286
private void activate(TaskNotificationSchedulerConfiguration configguration) {

this.contentDampath = configguration.assetPath();
this.schedulerName = configguration.schdulerName();
logger.info("**** Task Notification Scheduler ****");
//This scheduler will continue to run automatically even after the server reboot, otherwise the scheduled tasks will stop running after the server reboot.
addScheduler(configguration);
}

@9182423
protected void modified(TaskNotificationSchedulerConfiguration configguration) {
// Remove the scheduler registered with old configuration
removeScheduler(configguration);

contentDampath = configguration.assetPath();
// Add the scheduler registered with new configuration
addScheduler(configguration);

}

private void addScheduler(TaskNotificationSchedulerConfiguration configguration) {

boolean enabled = configguration.enabled();
if (enabled) {
ScheduleOptions scheduleOptions = scheduler.EXPR(configguration.cronExpression());

if (!Strings.isNullOrEmpty(schedulerName)) {
scheduleOptions.name(schedulerName);
scheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, scheduleOptions);
logger.info("****** Task Notification Scheduler has been added successfully ******");

}

} else {
logger.info("****** Task Notification Scheduler is in disable state ******");
}

}

@3038739
protected void deactivated(TaskNotificationSchedulerConfiguration configguration) {
logger.info("**** Removing Task Notification Scheduler Successfully on deactivation ****");
removeScheduler(configguration);
}

private void removeScheduler(TaskNotificationSchedulerConfiguration configguration) {

logger.info("**** Removing Task Notification Scheduler Successfully **** {}", schedulerName);
scheduler.unschedule(schedulerName);

}

@9944223
public void run() {
taskNotificationService.setTaskNotification(contentDampath);
logger.info("******Inside Task Notification Scheduler ******");

}

}

 

 

Impl -

 

/**
*
*/
package com.aem.demo.core.services.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ModifiableValueMap;
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.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.granite.taskmanagement.Task;
import com.adobe.granite.taskmanagement.TaskManager;
import com.adobe.granite.taskmanagement.TaskManagerException;
import com.adobe.granite.taskmanagement.TaskManagerFactory;
import com.adobe.granite.workflow.exec.InboxItem;
import com.aem.demo.core.services.TaskNotificationService;
import com.drew.lang.annotations.Nullable;
import com.google.common.base.Strings;

/**
* @380 debal
*
* This Implementation class is responsible to responsible to set/send
* notification in AEM inbox in case we set expiration datetime of an
* asset after current date time. Task Management in AEM is the set of
* APIs that manage Tasks, which can show up in AEM user's inbox. This
* can be done using Task and TaskManager API
*/
@8220494(service = TaskNotificationService.class, immediate = true)
public class TaskNotificationServiceImpl implements TaskNotificationService {

private final Logger logger = LoggerFactory.getLogger(TaskNotificationServiceImpl.class);

public static final String NOTIFICATION_TASK_TYPE = "Notification";

@3214626
ResourceResolverFactory resourceResolverFactory;

@9944223
public void setTaskNotification(String assetPath) {

ResourceResolver serviceResourceResolver = getResourceResolver();

try {

TaskManager taskManager = serviceResourceResolver.adaptTo(TaskManager.class);
TaskManagerFactory taskManagerFactory = taskManager.getTaskManagerFactory();
if (!Strings.isNullOrEmpty(assetPath)) {
Resource resource = serviceResourceResolver.getResource(assetPath);
if (Objects.nonNull(resource) && resource.isResourceType("dam:Asset")) {
Resource metadataresource = resource.getChild("jcr:content/metadata");
ModifiableValueMap modifiableValueMap = metadataresource.adaptTo(ModifiableValueMap.class);

@3146596
String creatorName = modifiableValueMap.get("dc:creator", String.class);

@3146596
Date expirydate = modifiableValueMap.get("prism:expirationDate", Date.class);
logger.info("*** Expiration Date ***{}", expirydate);

Date currentDate = new Date();
if (Objects.nonNull(expirydate) && !Strings.isNullOrEmpty(creatorName)) {
if (expirydate.after(currentDate)) {
Task newTask = taskManagerFactory.newTask(NOTIFICATION_TASK_TYPE);
newTask.setName("Content Expiry Notification");
newTask.setContentPath(assetPath);
// Optionally set priority (High, Medium, Low)
newTask.setPriority(InboxItem.Priority.HIGH);
newTask.setDescription("Content Expiry Notification");
newTask.setInstructions("Content Expiry Notification");
newTask.setCurrentAssignee(creatorName);
taskManager.createTask(newTask);

}

}

}

}

} catch (TaskManagerException te) {
logger.error("Could not create task {} ", te.getMessage());
} finally {
if (Objects.nonNull(serviceResourceResolver)) {
serviceResourceResolver.close();
}

}
}

private ResourceResolver getResourceResolver() {
Map<String, Object> map = new HashMap<String, Object>();
map.put(resourceResolverFactory.SUBSERVICE, "readWriteService");
ResourceResolver serviceResourceResolver = null;
try {

serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(map);
} catch (LoginException e) {
logger.error("Could not get service user [ {} ]", "demoSystemUser", e.getMessage());
}
return serviceResourceResolver;

}

}

 

Interface -

 

/**
*
*/
package com.aem.demo.core.services;

/**
* @380 debal
*
* This service is responsible to set/send notification in AEM inbox
*/
public interface TaskNotificationService {

public void setTaskNotification(String assetPath);
}

 

 

Please review the comments at code level.

Anny0505
Anny0505Author
New Participant
January 21, 2022

test

DEBAL_DAS
New Participant
January 23, 2022

There won't be any problem if you create all required configurations in the scheduler it self.

 

I have tested your code -

Approach 1: Deployed your scheduler on my local AEM instance and then change the cronjob expression, scheduler got triggered.

 

Approach 2: Set the cronjob expression first and then deployed scheduler (bundle, which contains the scheduler), scheduler got triggered perfectly. 

 

I did these multiple times and scheduler got triggered every time.

 

 

 

As @joerghoh suggested , could you please check the threadpool also.

 

Are you still facing the same problem?

 

Raja-Karuppsamy
New Participant
January 20, 2022

Hi @anny0505 Can you verify the user permission of the scheduler script ? 

Also can you verify the cronjob expression of the scheduler ?

 

 

Regards,

Raja

Anny0505
Anny0505Author
New Participant
January 20, 2022

Yes,

 

String schedulerExpression() default "0 0 2 1/1 * ? *";

Anny0505
Anny0505Author
New Participant
January 20, 2022

which user permissions do I need to check?