Listening for Trigger Events
As with the JobListener, the org.quartz.TriggerListener interface contains a set of methods that the Scheduler calls. Unlike the JobListener, however, the triggerListener interface contains life cycle methods for trigger instances. Listing 7.5 shows the methods of the triggerListener interface.
Listing 7.5. The Methods of the org.quartz.TriggerListener Interface
public interface TriggerListener { public String getName(); public void triggerFired(Trigger trigger, JobExecutionContext context); public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context); public void triggerMisfired(Trigger trigger); public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode); } |
The getName() Method
As with the previous JobListener, the getName() method on the TRiggerListener interface returns a String that represents the name of the listener. For nonglobal TRiggerListeners, the name given in the addTriggerListener() method should match the value returned from the listener's gettName() method.
The triggerFired() Method
The Scheduler calls this method when the trigger associated with the listener has fired and the execute() method is about to be called on the job. In the case of a global triggerListener, this method is called for all triggers.
The vetoJobExecution() Method
The Scheduler calls this method when the trigger has fired and the job is about to be executed. The triggerListener is given a chance to veto the execution of the job. If this method returns true, the job will not be executed for this trigger firing.
The triggerMisfired() Method
The Scheduler calls this method when the trigger has misfired. As the JavaDocs for this method point out, you should be careful about performing long-lasting logic in this method: Doing so could cause a domino effect when there are many misfired triggers. You should keep the logic in this method to a minimum.
The TRiggerComplete() Method
The Scheduler calls this method when the trigger has fired and the job has finished executing. It doesn't mean that the trigger will not fire againjust that the current firing of the trigger (and subsequent job execution) has ended. The trigger might still have future firing times.
Listing 7.6 shows a very simple TRiggerListener implementation.
Listing 7.6. A Simplified triggerListener Implementation
package org.cavaness.quartzbook.chapter7; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobExecutionContext; import org.quartz.Trigger; import org.quartz.TriggerListener; public class SimpleTriggerListener implements TriggerListener { Log logger = LogFactory.getLog(SimpleTriggerListener.class); private String name; public SimpleTriggerListener(String name) { this.name = name; } public String getName() { return name; } public void triggerFired(Trigger trigger, JobExecutionContext context) { String triggerName = trigger.getName(); logger.info(triggerName + " was fired"); } public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) { String triggerName = trigger.getName(); logger.info(triggerName + " was not vetoed"); return false; } public void triggerMisfired(Trigger trigger) { String triggerName = trigger.getName(); logger.info(triggerName + " misfired"); } public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode) { String triggerName = trigger.getName(); logger.info(triggerName + " is complete"); } } |
Just as with the JobListener in Listing 7.2, the triggerListener in Listing 7.6 is rudimentary. It merely prints a log message when the Scheduler invokes the method. The code in Listing 7.7 tests the simple TRiggerListener.
Listing 7.7. Using the SimpleTriggerListener as a Global TRiggerListener
package org.cavaness.quartzbook.chapter7; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cavaness.quartzbook.common.PrintInfoJob; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerListener; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_7_7 { static Log logger = LogFactory.getLog(Listing_7_7.class); public static void main(String[] args) { Listing_7_7 example = new Listing_7_7(); try { example.startScheduler(); } catch (SchedulerException ex) { logger.error(ex); } } public void startScheduler() throws SchedulerException { // Create an instance of the factory Scheduler scheduler = null; // Create the scheduler and JobDetail scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create and register the global job listener TriggerListener triggerListener = new SimpleTriggerListener("SimpleTriggerListener"); scheduler.addGlobalTriggerListener(triggerListener); /* * Set up a trigger to start firing now, with no end * date/time, repeat forever and have 10 secs * (10000 ms) between each firing. */ Trigger trigger = TriggerUtils.makeSecondlyTrigger(10); trigger.setName("SimpleTrigger"); trigger.setStartTime(new Date()); // Register the JobDetail and Trigger scheduler.scheduleJob(jobDetail, trigger); // Start the scheduler scheduler.start(); logger.info("Scheduler was started at " + new Date()); } } |
Listing 7.7 shows how to register the SimpleTriggerListener as a global triggerListener. It looks almost identical to the code from Listing 7.3 that registered a global JobListener. You just need to call the addGlobalTriggerListener() method and pass it the triggerListener instance.
Registering a Nonglobal TRiggerListener
To register a nonglobal triggerListener, you need to call the addTriggerListener() method and pass the triggerListener instance. Then call the addTriggerListener() method on the trigger instance and pass the name of the triggerListener.
This is shown in Listing 7.8.
Listing 7.8. Using a Nonglobal triggerListener
package org.cavaness.quartzbook.chapter7; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cavaness.quartzbook.common.PrintInfoJob; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerListener; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_7_8 { static Log logger = LogFactory.getLog(Listing_7_8.class); public static void main(String[] args) { Listing_7_8 example = new Listing_7_8(); try { example.startScheduler(); } catch (SchedulerException ex) { logger.error(ex); } } public void startScheduler() throws SchedulerException { // Create an instance of the factory Scheduler scheduler = null; // Create the scheduler and JobDetail scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create and register the nonglobal job listener TriggerListener triggerListener = new SimpleTriggerListener("SimpleTriggerListener"); scheduler.addTriggerListener( triggerListener ); /* * Set up a trigger to start firing now, with no end * date/time, repeat forever and have 10 secs * (10000 ms) between each firing. */ Trigger trigger = TriggerUtils.makeSecondlyTrigger(10); trigger.setName("SimpleTrigger"); trigger.setStartTime(new Date()); // Set the listener name for the trigger trigger.addTriggerListener( triggerListener.getName() ); // Register the JobDetail and Trigger scheduler.scheduleJob(jobDetail, trigger); // Start the scheduler scheduler.start(); logger.info("Scheduler was started at " + new Date()); } } |
The same warning that we mentioned earlier for nonglobal JobListeners applies here: You should add the TRiggerListener to the Scheduler before setting it on the trigger instance and storing the trigger.
Listening for Scheduler Events
|