Cron Trigger,Jobs and Expressions in Quartz Scheduler

Cron triggers in Quartz can be used to schedule a job based on an expression ( more like a reg-ex) defining when precisely the job execution is allowed. The cron trigger can be used to schedule a job only on specific days of month, or a definite time range for specific days etc. The cron expression is a string which comprises of 7 elements of which 6 are mandatory.

Cron expression involves 6 or 7 fields in a string separated by whitespace. The fields and their allowed values are (individually or as a range) –

Seconds -> 0-59
Minutes -> 0-59
Hours -> 0-23
Day of month -> 1-31
Month –> 1-12 or JAN-DEC
Day of week -> 1-7 or SUN-SAT

And the optional field of
Year -> 1970-2099

Along with the literal values for the fields, a cron expression also allows a few general and specific ( for particular fields ) wildcard entries to be used in the string. General wildcard entries include “*” signifying any value from the allowed range of values, “,” signifying combination of values for example 1,2,3 for day of month, the range specifier “-“, the “/” wildcard entry, which signifies increment. For example using 2/10 in the minutes field signifies that the job has to be fired every 10th minute starting from the second minute of the hour i.e., 2nd ,12th ,22nd ,32nd ,42nd ,52nd minute of the hour and the “?” literal which signifies that there is no specific value. The “?” literal is used especially in cases of day of week and day of month where one might influence the other. For example, to specify all weekdays of a month, the “?” literal can be used in the field day of month and MON-FRI in day of week field so that cron is fired on all weekdays irrespective of the date

Some of the special wildcard entries which are specific to “day of month” field are L and W –where L specifies the last day of the month and W signifies the weekday closest to the given day, for example 10W specifies the weekday after 10th if the 10th falls on a weekend else the day itself. Please note that the usage of W does not spill-over to the next month, in that, if, 30W is specified then, if 30 and 31 are weekend then, the job is not executed on 1st of the next month but, is executed on the weekday next to 30th of the coming month.

The other wildcard entries are L and # used in the “day of week” field. The “L” entry has the same meaning here, in that, it signifies the last day of the week (ie., 7 or SAT ) also, it can be additionally used with a value from 1-7 which makes it the last particular day of the month – for example, 5L specifies the last Thursday of the month. The # wildcard entry on the other hand is used to specify the nth day of the month – for example 3#2 means second Tuesday of the month ( 3 -> Tuesday and #2 -> position in the month )

Let us convert our Alarm scheduler application from the previous posts to use a cron-tigger, so that the Alarm is scheduled only for the weekdays along with a break for Christmas –

Sample program – AlarmSchedule.java


import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Properties;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.AnnualCalendar;

public class AlarmSchedule {

	public AlarmSchedule(){
		try{
			//Create the annual calendar object - to add Christmas holiday to our Alarm Job fire exception
			AnnualCalendar holidays = new AnnualCalendar();
			Calendar christmas = new GregorianCalendar(2011, 11, 25);
			holidays.setDayExcluded(christmas, true);
			Properties prop = new Properties();
			prop.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
			prop.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
			prop.setProperty("org.quartz.threadPool.threadCount", "4");
			SchedulerFactory schdFact = new StdSchedulerFactory(prop);
			Scheduler schd = schdFact.getScheduler();
			//add the Calendar object created to the scheduler with a string identifier to it
			schd.addCalendar("holidays", holidays, false, true);
			schd.start();
			JobDetail jd = new JobDetail("alarmjob", Scheduler.DEFAULT_GROUP, AlarmJob.class);
			//Define a cron job such that the job executes every weekday at 06:00
			CronTrigger t = new CronTrigger("alarmtrigger", Scheduler.DEFAULT_GROUP, "0 0 6 ? * MON-FRI *");
			//set the calendar associated with the trigger
			t.setCalendarName("holidays");
			t.getJobDataMap().put("auth_name", "Vageesh");
			t.setStartTime(new Date());
			schd.addJobListener(new AlarmJobListener());
			jd.addJobListener("Alarm gone");
			schd.scheduleJob(jd, t);
			System.out.println(schd.getSchedulerName());
		}
		catch(SchedulerException e){
			e.printStackTrace();
		}
		catch(ParseException e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new AlarmSchedule();
	}
}

In the above program, the line


CronTrigger t = new CronTrigger("alarmtrigger", Scheduler.DEFAULT_GROUP, "0 0 6 ? * MON-FRI *");

creates a new cron-trigger that is scheduled for every weekday at 0600 hrs. The string “0 0 6 ? * MON-FRI *” specifies –

0 – 0th second
0 – 0th minute
6 – 6 AM hours
? – no specific day of the month
“*” – all months
MON-FRI – only weekdays
“*” – any year

Leave a comment