The Commons Scheduler
The scheduler is a service for scheduling other services/jobs (it uses the open source Quartz library). The scheduler can be used in two ways, by registering the job through the scheduler API and by leveraging the whiteboard pattern that is supported by the scheduler.
The Scheduler API
The scheduler has methods to execute jobs periodically, based on a cron _expression_ or at a given time. For more details please refer to the javadocs.
Examples of scheduled jobs registered through the scheduler API
The following examples show you how to define and schedule a job that is registered through the scheduler api.
Defining the job
The following code sample defines a job object that writes a message in the logs:
final Runnable job = new Runnable() {
public void run() {
log.info("Executing the job");
}
};
Scheduling with a cron _expression_
To execute the job as defined above at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday, you can use the addJob() method with the following parameters:
String schedulingExpression = "0 15 10 ? * MON-FRI";
this.scheduler.addJob("myJob", job, null, schedulingExpression, true);
Refer to http://www.docjar.com/docs/api/org/quartz/CronTrigger.html
to define more scheduling expressions.
Scheduling at periodic times
To execute the job as defined above every 3 minutes (180 seconds), you can use the addPeriodicJob() method with the following parameters:
long period = 3*60; this.scheduler.addPeriodicJob("myJob", job, null, period, true);
Scheduling at a given time
To execute the job as defined above at a specific date (on January 10th 2020), you can use the fireJobAt() method with the following parameters:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
String date = "2020/01/10";
java.util.Date fireDate = formatter.parse(date);
this.scheduler.fireJobAt("myJob", job, null, fireDate);
A service scheduling the job based on 3 different kinds of scheduling
The code implementing a service that simultaneously executes the job based on 3 different kinds of scheduling can look as follows:
package sling.docu.examples;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This service executes scheduled jobs
*
* @scr.component immediate="true" metatype="false"
*
*/
public class HelloWorldScheduledService {
/** Default log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
/** The scheduler for rescheduling jobs.
* @scr.reference */
private Scheduler scheduler;
protected void activate(ComponentContext componentContext) throws Exception {
String schedulingExpression = "0 * * * * ?";
String jobName1 = "case1";
Map<String, Serializable> config1 = new HashMap<String, Serializable>();
boolean canRunConcurrently = true;
final Runnable job1 = new Runnable() {
public void run() {
log.info("Executing job1");
}
};
try {
this.scheduler.addJob(jobName1, job1, config1, schedulingExpression, canRunConcurrently);
} catch (Exception e) {
job1.run();
}
String jobName2 = "case2";
long period = 180;
Map<String, Serializable> config2 = new HashMap<String, Serializable>();
final Runnable job2 = new Runnable() {
public void run() {
log.info("Executing job2");
}
};
try {
this.scheduler.addPeriodicJob(jobName2, job2, config2, period, canRunConcurrently);
} catch (Exception e) {
job2.run();
}
String jobName3 = "case3";
final long delay = 30*1000;
final Date fireDate = new Date();
fireDate.setTime(System.currentTimeMillis() + delay);
Map<String, Serializable> config3 = new HashMap<String, Serializable>();
final Runnable job3 = new Runnable() {
public void run() {
log.info("Executing job3 at date: {} with a delay of: {} seconds", fireDate, delay/1000);
}
};
try {
this.scheduler.fireJobAt(jobName3, job3, config3, fireDate);
} catch (Exception e) {
job3.run();
}
}
protected void deactivate(ComponentContext componentContext) {
log.info("Deactivated, goodbye!");
}
}
Examples of jobs that are scheduled by leveraging the whiteboard pattern
The following examples show you how to define and schedule a job by leveraging the whiteboard pattern.
Scheduling with a cron _expression_
The following job is executed every minute by setting scheduler._expression_ to the cron _expression_ "0 * * * * ?":
package sling.docu.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @scr.component
* @scr.service interface="java.lang.Runnable"
* @scr.property name="scheduler._expression_" value="0 * * * * ?"
*/
public class ScheduledCronJob implements Runnable {
/** Default log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
public void run() {
log.info("Executing a cron job (job#1) through the whiteboard pattern");
}
}
Scheduling at periodic times
The following job is executed every ten seconds by setting scheduler.period to 10:
package sling.docu.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @scr.component
* @scr.service interface="java.lang.Runnable"
* @scr.property name="scheduler.period" value="10" type="Long"
*/
public class ScheduledPeriodicJob implements Runnable {
/** Default log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
public void run() {
log.info("Executing a perodic job (job#2) through the whiteboard pattern");
}
}
Preventing concurrent execution
By default, jobs can be concurrently executed. To prevent this, set the scheduler.concurrent property to false:
@scr.property name="scheduler.concurrent" value="false" type="Boolean"