AEM Developer Series
- Day 00: AEM Developer Series
- Day 01: Introduction to AEM
- Day 02: AEM Architecture
- Day 03: Setting up AEM Development Environment
- Day 04: Developing First OSGi Bundle
- Day 05: Working with Sling Servlets in AEM
- Day 06: Playing with Sling Post Servlet
- Day 07: Creating your first component in AEM
- Day 08: Dueling with JavaScript Use API
- Day 09: Dueling with Java Use API
- Day 10: Getting to know Sling Models
- Day 11: Client Libraries in Action
- Day 12: Creating your custom OSGi Configuration
- Day 13: Schedulers in AEM
- Day 14: Eventing in AEM
- Day 15: Custom Workflows in AEM
- Day 16: Creating JMX Beans in AEM
- Day 17: Working with QueryBuilder API
- Day 18: Working with Granite Datasources in AEM
- Day 19: Replication API in Action
- Day 20: Working with Users and Groups in AEM
In AEM, we can create scheduler in two ways -
- Whiteboard Pattern - In this, we create a Runnable thread to perform our task. This is similar to the Java Thread concept.
- Scheduler API - In this, we use Apache Commons' Scheduler API to perform our task. It uses open-source Quartz library.
Scheduler in AEM
To create a scheduler in AEM, we will follow the below steps -
- Create an OSGi configuration to read the scheduler specific values from the user i.e. cron expression, the name of the scheduler, custom parameter etc.
- Create a sling scheduler which displays the custom parameter at an interval specified by the cron expression.
Without making further delay, let's dive into our code
Create an OSGi configuration
Follow this post to create a new OSGi configuration class and paste the following code in it.
Here we are getting configuration properties for the Sling Scheduler.
Create Scheduler
Now we are going to create a sling scheduler. Create a class named CustomScheduler and paste the following code in it.
- Let us understand the code step-by-step. First, we are registering the class as a service and implementing the Runnable interface. At the same time, using @Desginate annotation, we are linking the OSGi configuration created in the previous section with this class.
- Now, we are injecting the org.apache.sling.commons.scheduler.Scheduler dependency.
- In the activate() method, we are reading the required values. Then we are getting the schedulerId from the scheduler name.
- The modified() method recalculates the schedulerId in case the OSGi configuration is modified.
- In the addScheduler() method, we are registering the scheduler using the Scheduler API.
- The run() method will be defining our task. Here we are just printing the customParameter in the logs.
Configuring OSGi
- Go to ./system/console/configMgr and search for SlingSchedulerConfiguration and configure it like below screenshot.
![]() |
OSGi Configuration |
- Save the configuration.
Result
Now go to your project-specific log (my log file is - project-demoproject.log) and look for the traces, you will find like below
org.redquark.demo.core.schedulers.CustomScheduler Scheduler added
org.redquark.demo.core.schedulers.CustomScheduler Custom Scheduler is now running using the passed custom parameter, customParameter AEM Scheduler Demo
org.redquark.demo.core.schedulers.CustomScheduler Custom Scheduler is now running using the passed custom parameter, customParameter AEM Scheduler Demo
org.redquark.demo.core.schedulers.CustomScheduler Removing scheduler: -1760311957
org.redquark.demo.core.schedulers.CustomScheduler Scheduler added
org.redquark.demo.core.schedulers.CustomScheduler Custom Scheduler is now running using the passed custom parameter, customParameter AEM Scheduler Demo
org.redquark.demo.core.schedulers.CustomScheduler Custom Scheduler is now running using the passed custom parameter, customParameter AEM Scheduler Demo
Conclusion
Congratulations!! 🙋 we have successfully created a Sling Scheduler and I hope you enjoyed this post.
You can find the complete code of this project on my GitHub in this commit. Feel free to fork or open issues, if any.
I would love to hear your thoughts on this and would like to have suggestions from you to make it better.
Happy Coding 😃
Well explained . Great work. Hope this code will be executed AEM 6.3. Let me try this.
ReplyDeleteThanks
Shahid
Thanks Shahid for your valuable feedback. I am sure this will work on your AEM 6.3 as the only difference is the use of OSGi annotations instead of Felix SCR annotations. OSGi annotations are supported in AEM 6.3.
DeleteDo let me know in case you face issues executing the code.
Cheers!
Thanks for this great article. Huge help on a project that I'm currently working on.
ReplyDeleteThanks Anirudh. After having an issue with a scheduler not running (based on Archetype 14, running on AEM 6.3) I used some pointers from your setup to resolve my issue.
ReplyDeleteJust one interesting thing to note: I needed to add addScheduler(config); into my activate method. Not sure if you missed it, because in your code you only invoke addScheduler in the modify method
Scheduler enable/disable is not working, it is keep on executing after disabling the service.
ReplyDeleteThere is a bug, change "scheduleOptions.name(config.schdulerName());" to "scheduleOptions.name(String.valueOf(schedulerId));", will ok, use this.scheduleOptions.name(<>) to set a name to the job, later use the same name to cancel the job using scheduler.unschedule(<>);
DeleteYou are right! See the latest version of this at - https://redquark.org/aem/day-16-schedulers-in-aem/
DeleteThis code will give a sonar exception as : The class uses Sling Commons Scheduler. It should use Sling Jobs instead.
ReplyDeletehey! finally i got good example in aem6.5. Its working good
ReplyDeleteThis is a great tutorial, and the only one of its kind I have found so far. One thing is not clear though: is there a way to define the variables before hand? This tutorial creates a service which allows the user to edit variables via the configMgr, which is great for run time tuning, but we dont what to have to hand set all the variables for each env. We want to define the variables values for each run mode or similar via a file, so that they start off correct without manual intervention. Any suggestions?
ReplyDeleteHi Anirudh,
ReplyDeleteDo you have any resources for creating a scheduler by getting a path of the folder from local AEM and generating a list of the nodes under the folder?
This should not be tough. You can use javax.jcr.Node API to get the required details. You can put this business logic in the overridden run method.
DeleteIs it for AEM on OSGi or AEM on JEE? Or say is it applicable for both?
ReplyDelete