Quartz
- Quartz is an open source job scheduling framework written in Java.
- Quartz contains all of the core Quartz functionality and it is distributed as a small java library (quartz.jar).
- Scheduler Interface is the main interface (API) which provides some simple operations like scheduling jobs, unscheduling jobs, starting/stopping/pausing the scheduler.
- If we want a scheduler in our application, then we must implement the Job Interface and override the execute() method.
- We implement the TriggerListener or JobListener interface when we want to be notified when the scheduled trigger time arrives.
- When the Scheduler determines the notifying time to your job, the Quartz framework will call the execute() method on your Job class.
Now let’s see how to create a scheduler and use it.
The first step is to instantiate the scheduler using ‘SchedulerFactory’
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
Once a scheduler is instantiated, it can be started, paused, and shutdown. Note that once a scheduler is shutdown, it cannot be restarted without being re-instantiated. Triggers do not fire (jobs do not execute) until the scheduler has been started, nor while it is in the paused state.
Now let’s start the scheduler and schedule a job for execution
sched.start();
JobDetail jobDetail = new JobDetail(“myJob”, sched.DEFAULT_GROUP, MyJob.class); // MyJob.class is the Job class
SimpleTrigger trigger = new SimpleTrigger(“myTrigger”, sched.DEFAULT_GROUP, new Date(), null, 0, 0L);
sched.scheduleJob(jobDetail, trigger);
Job Detail
Quartz needs to be informed about various attributes that you may wish the job to have. This is done via the JobDetail class through it arguments -’ job name,
job group and the java class to execute‘ respectively.
The JobDetail object is created by the Quartz client (your program) at the time the Job is added to the scheduler.
Every time the scheduler gets executed, a new instance of the Job class is created.
Suppose, you want to pass some properties/configuration to the job instance. In that case we use JobDataMap, which is a part of the JobDetail object.
The JobDataMap can be used to hold any number of (serializable) objects which you wish to have made available to the job instance when it executes. JobDataMap is an implementation of the Java Map interface, and has some added convenience methods for storing and retreiving data of primitive types.
jobDetail.getJobDataMap( ).put(“adminEmail”, “admin@apple.com”) ;
And we can read this configuration parameter in our Job class by including this code snippet in the execute() method
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String adminEmail = dataMap.getString(“adminEmail”);
Stateful vs. Non-Stateful Jobs
Non-stateful jobs only have their JobDataMap stored at the time they are added to the scheduler.
Any changes made to the contents of the job data map during execution of the job will be lost, and will not seen by the job the next time it executes.
For Stateful Jobs, JobDataMap is re-stored after every execution of the job but this means that the jobs cannot be executed concurrently. A job can be made Stateful by implementing the interface StatefulJob instead of the Job interface.
The other attributes of a Job
- Durability if a job is non-durable, it is automatically deleted from the scheduler once there are no longer any active triggers associated with it.
- Volatility – if a job is volatile, it is not persisted between re-starts of the Quartz scheduler.
- Request Recovery – if a job “requests recovery”, and it is executing during the time of a ‘hard shutdown’ of the scheduler (i.e. the process it is running within crashes, or the machine is shut off), then it is re-executed when the scheduler is started again. In this case, the JobExecutionContext.isRecovering() method will return true.
- Job Listeners = a job can have a set of zero or more JobListeners associated with it. When the job executes, the listeners are notified.
Jobs
We can make Java component executable by the scheduler simply by making it implement the Job interface.
package org.quartz;
public interface Job {
public void execute(JobExecutionContext context) throws JobExecutionException;
}
When the Job’s trigger fires (more on that in a moment), the execute(..) method is invoked by the scheduler.
Triggers
Trigger objects are used to trigger the execution (or ‘firing’) of jobs. When you wish to schedule a job, you instantiate a trigger and ‘tune’ its properties to provide the scheduling you wish to have.
There are currently two types of triggers, SimpleTrigger and CronTrigger.
SimpleTrigger is handy if you need ‘one-shot’ execution (just single execution of a job at a given moment in time), or if you need to fire a job at a given time, and have it repeat N times, with a delay of T between executions.
CronTrigger is useful if you wish to have triggering based on calendar-like schedules – such as “every Friday, at noon” or “at 10:15 on the 10th day of every month.”