Quartz Scheduler Cron Expression Example
Quartz scheduler offers two kind of triggers, simple trigger and cron trigger. If the schedule is based on specified intervals then a simple trigger will do but if your job needs to be fired based on calendar-like notions then you need to use cron triggers. For example, every Wednesday at 12:00:00 pm. From the name you can guess, cron expressions are based on the unix tool cron. We will use the cron expressions to build cron trigger. In this article, we will see examples of Quartz scheduler’s cron expressions.
Before we start with the example, let’s look into the basics.
1. What is Quartz?
Quartz is a Java open source job-scheduling system capable of scheduling and executing jobs. In this example, we use the latest stable Quartz available which is version 2.2.1.
- You can download Quartz from http://quartz-scheduler.org/downloads
Ok, we know what is Quartz but what is job here? A job is a Java class containing the task to be executed but how do we schedule it?. We schedule the job using the trigger which defines when to execute the job. We now know the basic components that Quartz is made up of. Once we start with an example you will know their roles. Let’s start with the Quartz setup.
2. Quartz Setup
In this example, we will use Maven as the build tool so all you need to do is add the below dependency to pom.xml which looks like below.
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.camel</groupId> <artifactId>camelHelloWorld</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> </dependencies> </project>
Let’s begin our article with an example.
3. Example of Cron Expression
In our example, we first create a schedule, a job that needs to be executed, a trigger that defines when to execute and then finally scheduling the job. Our focus is on the cron trigger. We want to fire a job every day starting at 10:20:20. The time at which the first job fires is just a minute from now. Assuming the current time is 23:23:45, the cron expression would be “0 24 23 * * ? *”. The * defines
Here is the cron expression class which we will later use to build the trigger and schedule the job. CronTrigger instances are built using TriggerBuilder (for the trigger’s main properties)
and CronScheduleBuilder.
CronExpressionsExample:
package com.javacodegeeks.quartz; import org.quartz.CronScheduleBuilder; import org.quartz.DateBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; public class CronExpressionsExample { private static final String GROUP_NAME = "CroneExamples"; // Fire at current time + 1 min every day public static Trigger fireAfterAMinEveryDayStartingAt(int startHr, int startMin, int startSec, int nowMin, int nowHr) { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireAfterAMinStartingAt", GROUP_NAME) .startAt(DateBuilder.todayAt(startHr, startMin, startSec)) .withSchedule(CronScheduleBuilder.cronSchedule("0 " + (nowMin + 1) + " " + nowHr + " * * ? *")) .build(); return trigger; } }
In order to understand the cron expression “0 24 23 * * ? *” and the individual components we need to understand its sub-expressions.
4. Cron Expression Components
Cron-Expressions are strings that are actually made up of seven sub-expressions. Each sub-expression describes the individual details of the schedule. These sub-expression are separated with white-space.
The sub-expressions represent the following components:
- Seconds
- Minutes
- Hours
- Day-of-Month
- Month
- Day-of-Week
- Year (optional field)
In our example, we have used wild cards * and ?. Wild-cards * means “every” possible value of this field whereas wild card? is used to specify “no specific value”. It is allowed for the day-of-month and day-of-week fields. Cron expression “0 24 23 * * ? *” means the job will fire at time 23:24:00 every day.
QuartzSchedulerCronTriggerExample:
package com.javacodegeeks.quartz; import java.util.Calendar; import java.util.Date; import java.util.concurrent.CountDownLatch; import org.quartz.JobBuilder; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; public class QuartzSchedulerCronTriggerExample implements ILatch { private CountDownLatch latch = new CountDownLatch(1); public static void main(String[] args) throws Exception { QuartzSchedulerCronTriggerExample quartzSchedulerExample = new QuartzSchedulerCronTriggerExample(); quartzSchedulerExample.fireJob(); } public void fireJob() throws SchedulerException, InterruptedException { SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); Scheduler scheduler = schedFact.getScheduler(); scheduler.start(); // define the job and tie it to our HelloJob class JobBuilder jobBuilder = JobBuilder.newJob(MyJob.class); JobDataMap data = new JobDataMap(); data.put("latch", this); JobDetail jobDetail = jobBuilder.usingJobData("example", "com.javacodegeeks.quartz.QuartzSchedulerListenerExample") .usingJobData(data) .withIdentity("myJob", "group1") .build(); Calendar rightNow = Calendar.getInstance(); int hour = rightNow.get(Calendar.HOUR_OF_DAY); int min = rightNow.get(Calendar.MINUTE); System.out.println("Current time: " + new Date()); // Tell quartz to schedule the job using our trigger // Fire at current time + 1 min every day scheduler.scheduleJob(jobDetail, CronExpressionsExample.fireAfterAMinEveryDayStartingAt(10, 20, 20, hour, min)); latch.await(); System.out.println("All triggers executed. Shutdown scheduler"); scheduler.shutdown(); } public void countDown() { latch.countDown(); } }
MyJob:
package com.javacodegeeks.quartz; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class MyJob implements Job { private static int count; public void execute(JobExecutionContext jobContext) throws JobExecutionException { System.out.println("--------------------------------------------------------------------"); System.out.println("MyJob start: " + jobContext.getFireTime()); JobDetail jobDetail = jobContext.getJobDetail(); System.out.println("Example name is: " + jobDetail.getJobDataMap().getString("example")); System.out.println("MyJob end: " + jobContext.getJobRunTime() + ", key: " + jobDetail.getKey()); System.out.println("MyJob next scheduled time: " + jobContext.getNextFireTime()); System.out.println("--------------------------------------------------------------------"); ILatch latch = (ILatch) jobDetail.getJobDataMap().get("latch"); latch.countDown(); count++; System.out.println("Job count " + count); } }
ILatch:
package com.javacodegeeks.quartz; public interface ILatch { void countDown(); }
Output:
Current time: Tue Sep 15 23:23:45 IST 2015 Fire every day starting at (10:20:20), start the job in a min from now->(0 24 23 * * ? *) -------------------------------------------------------------------- MyJob start: Tue Sep 15 23:24:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 23:24:00 IST 2015 -------------------------------------------------------------------- Job count 1 All triggers executed. Shutdown scheduler
5. Allowed Values in Cron Expressions
The sub-expressions represent the following components. Let’s go through each component and take a note of the valid values.
- Seconds
- Minutes
- Hours
- Day-of-Month
- Month
- Day-of-Week
- Year (optional field)
6. Seconds and Minutes
Valid values for seconds and minutes are 0 to 59. Of course you can also use wild-cards which we will review in a separate section.
7. Hours
Valid values are 0 to 23 for hours.
8. Day of Month
In numerical form, 1-31, but you need to be careful about how many days are in a given month.
9. Months
Months can be specified both in numerical as well as string. For example, in string, using JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC. Months can also be specified using a numerical value between 0 and 11.
10. Day of Week
The day of the week can contain ranges strings SUN, MON, TUE, WED, THU, FRI and SAT. It can also use the numerical value instead, for example, any value between 1 and 7, starting Sunday (1).
We can also specify ranges like “MON-FRI”, “MON,WED,FRI”, or even “MON-WED,SAT”.
11. Special Characters in Cron Expressions
*
used to say “every” possible value of this field./
can be used to specify increments to values. For example, if you put ‘0/10’ in the Minutes field, it means ‘every 10th minute of the hour, starting at minute zero’.?
is allowed for the day-of-month and day-of-week fields. It is used to specify “no specific value”. This is useful when you need to specify something in one of
the two fields, but not the other.L
character is allowed only for the day-of-month and day-of-week fields. It means “last”, for example, L in the day-of-month field means “the last day of the month”W
is used to specify the weekday (Monday-Friday) nearest the given day. For an example, if you were to specify “15W” as the value for the day-of-month field, it would mean “the nearest weekday to the 15th of the month”.- The
#
is used to specify “the nth” XXX weekday of the month. For example, the value of “6#3” or “FRI#3” in the day-of-week field means “the third Friday of the month”. -
is used to specify ranges. For example, “10-12” in the hour field means “the hours 10, 11 and 12.”,
use comma separated values to specify additional values. For example, “MON,WED,FRI”
12. Examples of Cron Expressions
Below are some more cron expressions for various scenarios.
0 0 15 10 * * 20015
– Fire at 10:15am every day during the year 20150 0 10-15 * * ?
– Fire between 10AM and 3PM every day0 0 10-15 * * SAT-SUN
– Fire between 10AM and 3PM on weekends SAT-SUN0 0 10 14,18,21 * ?
– Fire only on certain days of month (14,18 and 21)0 46/2 7 * * ?
– Fire every 2 minutes starting at 7:46am and ending at 7:58am, every day
Let’s improve our CronExpressionsExample
and add new methods to schedule jobs according to the above crone expressions.
CronExpressionsExample:
package com.javacodegeeks.quartz; import org.quartz.CronScheduleBuilder; import org.quartz.DateBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; public class CronExpressionsExample { private static final String GROUP_NAME = "CroneExamples"; // Fire at current time + 1 min every day public static Trigger fireAfterAMinEveryDayStartingAt(int startHr, int startMin, int startSec, int nowHr, int nowMin) { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireAfterAMinStartingAt", GROUP_NAME) .startAt(DateBuilder.todayAt(startHr, startMin, startSec)) .withSchedule(cronSchedule("Fire every day starting at (" + startHr + ":" + startMin + ":" + startSec + "), start the job in a min from now", "0 " + (nowMin + 1) + " " + nowHr + " * * ? *")) .build(); return trigger; } // Fire at 10:15am every day during the year 2015 public static Trigger fireAt1015MinEveryDayDuring2015() { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireAt1015MinEveryDayDuring2015", GROUP_NAME) .withSchedule(cronSchedule("Fire at 10:15am every day during the year 2015", "0 0 15 10 * * 20015")) .build(); return trigger; } // Fire between 10AM and 3PM every day public static Trigger fireBetween10To3EveryDay() { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireBetween10To3EveryDay", GROUP_NAME) .withSchedule(cronSchedule("Fire between 10AM and 3PM every day", "0 0 10-15 * * ?")) .build(); return trigger; } // Fire between 10AM and 3PM on weekends SAT-SUN public static Trigger fireBetween10to3OnWeekends() { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireBetween10to3OnWeekends", GROUP_NAME) .withSchedule(cronSchedule("Fire between 10AM and 3PM on weekends SAT-SUN", "0 0 10-15 * * SAT-SUN")) .build(); return trigger; } // Fire only on certain days of month (14,18 and 21) public static Trigger fireOnlyOnCertainDaysInMonth() { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireOnlyOnCertainDaysInMonth", GROUP_NAME) .withSchedule(cronSchedule("Fire only on certain days of month", "0 0 10 14,18,21 * ?")) .build(); return trigger; } //Fire every 2 minutes starting at 7:46am and ending at 7:58am, every day public static Trigger fireAfterTwoMinFrom7_46To7_58() { Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("fireAfterTwoMinFrom7_46To7_58", GROUP_NAME) .withSchedule(cronSchedule("Fire only on certain days of month", "0 46/2 7 * * ?")) .build(); return trigger; } private static CronScheduleBuilder cronSchedule(String desc, String cronExpression) { System.out.println(desc + "->(" + cronExpression + ")"); return CronScheduleBuilder.cronSchedule(cronExpression); } }
Let’s try running one of the cron trigger. In QuartzSchedulerCronExpressionExample
, we don’t shutdown scheduler explicitly and let it run indefinitely so that it can run jobs scheduled at different times.
13. Run the Cron Expression
We will now try running CronExpressionsExample.fireAfterTwoMinFrom7_46To7_58()
. Change your system time to 46 mins and then run the example so that the scheduler picks up the job. The cron expression 0 46/2 7 * * ?
will fire the job every 2 minutes starting at 7:46am and ending at 7:58am, every day. We will just try for today :-), obviously.
QuartzSchedulerCronExpressionsExample:
package com.javacodegeeks.quartz; import java.util.Date; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; public class QuartzSchedulerCronExpressionExample { public static void main(String[] args) throws Exception { QuartzSchedulerCronExpressionExample quartzSchedulerExample = new QuartzSchedulerCronExpressionExample(); quartzSchedulerExample.fireJob(); } public void fireJob() throws SchedulerException, InterruptedException { SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); Scheduler scheduler = schedFact.getScheduler(); scheduler.start(); // define the job and tie it to our HelloJob class JobBuilder jobBuilder = JobBuilder.newJob(MyJob.class); JobDetail jobDetail = jobBuilder.usingJobData("example", "com.javacodegeeks.quartz.QuartzSchedulerListenerExample") .withIdentity("myJob", "group1") .build(); System.out.println("Current time: " + new Date()); // Tell quartz to schedule the job using our trigger // Fire at current time + 1 min every day scheduler.scheduleJob(jobDetail, CronExpressionsExample.fireAfterTwoMinFrom7_46To7_58()); } }
You can see the job starts at Wed Sep 16 07:48:00 IST 2015. It fires job every 2 mins. The job firs 6 times. The last output statement has the next schedule time which is Thu Sep 17 07:46:00 IST 2015, that is, next day.
Output:
Current time: Wed Sep 16 07:46:24 IST 2015 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Current time: Wed Sep 16 07:46:24 IST 2015 Fire every 2 minutes starting at 7:46am and ending at 7:58am, every day->(0 46/2 7 * * ?) -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:48:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 07:50:00 IST 2015 -------------------------------------------------------------------- Job count 1 -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:50:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 07:52:00 IST 2015 -------------------------------------------------------------------- Job count 2 -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:52:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 07:54:00 IST 2015 -------------------------------------------------------------------- Job count 3 -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:54:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 07:56:00 IST 2015 -------------------------------------------------------------------- Job count 4 -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:56:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Wed Sep 16 07:58:00 IST 2015 -------------------------------------------------------------------- Job count 5 -------------------------------------------------------------------- MyJob start: Wed Sep 16 07:58:00 IST 2015 Example name is: com.javacodegeeks.quartz.QuartzSchedulerListenerExample MyJob end: -1, key: group1.myJob MyJob next scheduled time: Thu Sep 17 07:46:00 IST 2015 -------------------------------------------------------------------- Job count 6
14. Download the Eclipse Project
This was an example about Quartz Scheduler Cron Expressions.
You can download the full source code of this example here: cronExpressionsExample.zip
How to run Quartz Scheduler Cron Expression Example ?