The JobDetail object is created by the Quartz client (your program) at the time the Job is added to the scheduler. It
contains various property settings for the Job, as well as a JobDataMap, which can be used to store state information
for a given instance of your job class.
Trigger objects are used to trigger the execution (or 'firing') of jobs.Triggers may also have a JobDataMap associated
with them - this is useful to passing parameters to a Job that are specific to the firings of the trigger.
CronTrigger is useful if you wish to have triggering based on calendar-like schedules.
Jobs and Triggers are given identifying names as they are registered with the Quartz scheduler. The name of a job or
trigger must be unique within its group. If you leave the group of the Job or Trigger 'null', it is equivalent to having
specified Scheduler.DEFAULT_GROUP.
The JobDataMap can be used to hold any number of (serializable) objects.
The JobDataMap that is found on the JobExecutionContext during Job execution serves as a convenience. It is a merge of
the JobDataMap found on the JobDetail and the one found on the Trigger, with the value in the latter overriding any
same-named values in the former.
A Job instance can be defined as "stateful" or "non-stateful". If a job is stateful, and a trigger attempts to 'fire'
the job while it is already executing, the trigger will block (wait) until the previous execution completes.
You 'mark' a Job as stateful by having it implement the StatefulJob interface, rather than the Job interface.
You may want to create your own implementation of JobFactory to accomplish things such as having your application's IoC
or DI container produce/initialize the job instance.
The only type of exception (including RuntimeExceptions) that you are allowed to throw from the execute method is the
JobExecutionException. Because of this, you should generally wrap the entire contents of the execute method with a 'try
-catch' block, your job can use it to provide the scheduler various directives as to how you want the exception to be
handled.
Quartz Calendars are useful for excluding blocks of time from the the trigger's firing schedule.
Sometimes, when you have many Triggers (or few worker threads in your Quartz thread pool), Quartz may not have enough
resources to immediately fire all of the Triggers that are scheduled to fire at the same time.
A misfire occurs if a persistent trigger "misses" its firing time because of the scheduler being shutdown, or because
there are no available threads in Quartz's thread pool for executing the job. The misfire instruction for a given
trigger instance can be configured using the setMisfireInstruction(..) method.
The TriggerUtils class (in the org.quartz package) contains conveniences to help you create triggers and dates without
having to monkey around with java.util.Calendar objects.
Objects implementing the TriggerListener interface will receive notifications as a trigger is fired.
Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up
of seven sub-expressions, that describe individual details of the schedule. These sub-expression are separated with
white-space, and represent:
Seconds
Minutes
Hours
Day-of-Month
Month
Day-of-Week
Year (optional field)
Individual sub-expressions can contain ranges and/or lists. For example, the day of week field in the previous (which
reads "WED") example could be replaces with "MON-FRI", "MON, WED, FRI", or even "MON-WED,SAT".
Wild-cards (the '*' character) can be used to say "every" possible value of this field. Therefore the '*' character in
the "Month" field of the previous example simply means "every month". A '*' in the Day-Of-Week field would obviously
mean "every day of the week".
All of the fields have a set of valid values that can be specified. These values should be fairly obvious - such as the
numbers 0 to 59 for seconds and minutes, and the values 0 to 23 for hours. Day-of-Month can be any value 0-31, but you
need to be careful about how many days are in a given month! Months can be specified as values between 0 and 11, or by
using the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC. Days-of-Week can be specified as vaules
between 1 and 7 (1 = Sunday) or by using the strings SUN, MON, TUE, WED, THU, FRI and SAT.
The '/' character can be used to specify increments to values. For example, if you put '0/15' in the Minutes field, it
means 'every 15 minutes, starting at minute zero'. If you used '3/20' in the Minutes field, it would mean 'every 20
minutes during the hour, starting at minute three' - or in other words it is the same as specifying '3,23,43' in the
Minutes field.
The '?' character 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. See the examples below
(and CronTrigger JavaDoc) for clarification.
The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but
it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last
day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by
itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx
day of the month" - for example "6L" or "FRIL" both mean "the last friday of the month". When using the 'L' option, it
is important not to specify lists, or ranges of values, as you'll get confusing results.
The 'W' is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify
"15W" as the value for the day-of-month field, the meaning is: "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".
JobStore's are responsible for keeping track of all the "work data" that you give to the scheduler. Never use a JobStore
instance directly in your code.
RAMJobStore and JDBCJobStore.
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS