Lesson 4: More About Triggers

Like jobs, triggers are relatively easy to work with, but do contain a variety of customizable options that you need to be aware of and understand before you can make full use of Quartz. Also, as noted earlier, there are different types of triggers, that you can select to meet different scheduling needs.

Calendars

Quartz Calendar objects (not java.util.Calendar objects) can be associated with triggers at the time the trigger is stored in the scheduler. Calendars are useful for excluding blocks of time from the the trigger's firing schedule. For instance, you could create a trigger that fires a job every weekday at 9:30 am, but then add a Calendar that excludes all of the business's holidays.

Calendar's can be any serializable objects that implement the Calendar interface, which looks like this:

Calendar Interface
package org.quartz;

  public interface Calendar {

    public boolean isTimeIncluded(long timeStamp);

    public long getNextIncludedTime(long timeStamp);

  }

Notice that the parameters to these methods are of the long type. As you may guess, they are timestamps in millisecond format. This means that calendars can 'block out' sections of time as narrow as a millisecond. Most likely, you'll be interested in 'blocking-out' entire days. As a convenience, Quartz includes the class org.quartz.impl.HolidayCalendar, which does just that.

Calendars must be instantiated and registered with the scheduler via the addCalendar(..) method. If you use HolidayCalendar, after instantiating it, you should use its addExcludedDate(Date date) method in order to populate it with the days you wish to have excluded from scheduling. The same calendar instance can be used with multiple triggers such as this:

Using Calendars
HolidayCalendar cal = new HolidayCalendar();
  cal.addExcludedDate( someDate );

  sched.addCalendar("myHolidays", cal, false);

  Trigger trigger = TriggerUtils.makeHourlyTrigger(); // fire every one hour interval
  trigger.setStartTime(TriggerUtils.getEvenHourDate(new Date()));  // start on the next even hour
  trigger.setName("myTrigger1");

  trigger.setCalendarName("myHolidays");

  // .. schedule job with trigger

  Trigger trigger2 = TriggerUtils.makeDailyTrigger(8, 0); // fire every day at 08:00
  trigger.setStartTime(new Date()); // begin immediately
  trigger2.setName("myTrigger2");

  trigger2.setCalendarName("myHolidays");

  // .. schedule job with trigger2

The details of the values passed in the SimpleTrigger constructors will be explained in the next section. For now, just believe that the code above creates two triggers: one that will repeat every 60 seconds forever, and one that will repeat five times with a five day interval between firings. However, any of the firings that would have occurred during the period excluded by the calendar will be skipped.

Misfire Instructions

Another important property of a Trigger is its "misfire instruction". A misfire occurs if a persistent trigger "misses" its firing time because of the scheduler being shutdown. The different trigger types have different misfire instructions available to them. By default they use a 'smart policy' instruction - which has dynamic behavior based on trigger type and configuration. When the scheduler starts, it searches for any persistent triggers that have misfired, and it then updates each of them based on their individually configured misfire instructions. When you start using Quartz in your own projects, you should make yourself familiar with the misfire instructions that are defined on the given trigger types, and explained in their JavaDOC. More specific information about misfire instructions will be given within the tutorial lessons specific to each trigger type. The misfire instruction for a given trigger instance can be configured using the setMisfireInstruction(..) method.

TriggerUtils - Triggers Made Easy

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. Use this class to easily make triggers that fire every minute, hour, day, week, month, etc. Also use this class to generate dates that are rounded to the nearest second, minute or hour - this can be very useful for setting trigger start-times.

TriggerListeners

Finally, triggers may have registered listeners, just as jobs may. Objects implementing the TriggerListener interface will receive notifications as a trigger is fired.