Listening for Job Events

The org.quartz.JobListener interface contains a set of methods that are invoked when certain key events occur in the life cycle of a job. The methods available for JobListener are shown in Listing 7.1.

Listing 7.1. Methods of the org.quartz.JobListener Interface

public interface JobListener {
 public String getName();
 public void jobToBeExecuted(JobExecutionContext context);
 public void jobExecutionVetoed(JobExecutionContext context);

 public void jobWasExecuted(JobExecutionContext context,
 JobExecutionException jobException);
}

The methods in the JobListener interface are fairly self-explanatory. However, we should make a few points about them.

The getName() Method

The getName() method returns a String that represents the name of the JobListener. For listeners that are registered as global, the getName() method is primarily used for logging. However, for JobListeners that are referenced by specific jobs, the listener name registered with the JobDetail must match the value returned from the getName() method on the listener instance. This will be more obvious after you see a few examples.

The jobToBeExecuted() Method

The Scheduler calls this method when the JobDetail is about to be executed.

The jobExecutionVetoed() Method

The Scheduler calls this method when the JobDetail was about to be executed but a triggerListener vetoed the execution.

The jobWasExecuted() Method

The Scheduler calls this method after the JobDetail is executed.

Listing 7.2 shows a very simple JobListener implementation.

Listing 7.2. A Simplified JobListener 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.JobExecutionException;
import org.quartz.JobListener;

public class SimpleJobListener implements JobListener {
 Log logger = LogFactory.getLog(SimpleJobListener.class);

 public String getName() {
 return getClass().getSimpleName();
 }

 public void jobToBeExecuted(JobExecutionContext context) {
 String jobName = context.getJobDetail().getName();
 logger.info(jobName + " is about to be executed");
 }
 public void jobExecutionVetoed(JobExecutionContext context) {
 String jobName = context.getJobDetail().getName();
 logger.info(jobName + " was vetoed and not executed()");
 }
 public void jobWasExecuted(JobExecutionContext context,
 JobExecutionException jobException) {

 String jobName = context.getJobDetail().getName();
 logger.info(jobName + " was executed");
 }
}

The JobListener in Listing 7.2 prints a log message, which, obviously, is a basic use of the Listener. The logic that you implement is entirely up to you and your application needs. You might want to send an e-mail when a job finishes successfully or schedule another job after one gets vetoedyou have the freedom to perform just about any action from within the callback method.

Earlier we stated that JobListeners (and triggerListeners) can be either global or nonglobal. Notice that we didn't have to know in advanced whether the JobListener in Listing 7.2 was a global or nonglobal listener: We just implemented the interface and provided the listener methods. Listing 7.3 illustrates how to use the SimpleJobListener from Listing 7.2 and register it as global JobListener.

Listing 7.3. Using the SimpleJobListener as a Global JobListener

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.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class Listing_7_3 {
 static Log logger = LogFactory.getLog(Listing_7_3.class);

 public static void main(String[] args) {
 Listing_7_3 example = new Listing_7_3();

 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);

 /*
 * 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);

 // Create and register the global job listener
 JobListener jobListener =
 new SimpleJobListener("SimpleJobListener");

 scheduler.addGlobalJobListener(jobListener);
 // Start the scheduler
 scheduler.start();
 logger.info("Scheduler was started at " + new Date());
 }
}

The code in Listing 7.3 should be pretty straightforward by now. A JobDetail and trigger are created and registered with a Scheduler instance, just as we've done many times before.

A SimpleJobListener from Listing 7.2 is instantiated and registered with the Scheduler as a global JobListener by calling the addGlobalJobListener() method. Finally, the Scheduler is started.

Because we set up a single job (the PrintInfoJob), we get callbacks for only that JobDetail. However, if we had scheduled another job, we would also see callback log messages for the second job because the listener was configured as a global listener.

Registering Nonglobal JobListeners

You can also use the SimpleJobListener from Listing 7.2 as a nonglobal JobListener. To do this, you would only need to modify the code in the startScheduler() method from Listing 7.3. Listing 7.4 illustrates the small change that would need to be made.

Listing 7.4. Using the SimpleJobListener as a Nonglobal JobListener

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.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class Listing_7_4 {
 static Log logger = LogFactory.getLog(Listing_7_4.class);

 public static void main(String[] args) {
 Listing_7_4 example = new Listing_7_4();

 try {
 example.startScheduler();
 } catch (SchedulerException ex) {
 logger.error(ex);
 }
 }

 public void startScheduler() throws SchedulerException {

 Scheduler scheduler = null;

 try {
 // Create the scheduler and JobDetail
 scheduler = StdSchedulerFactory.getDefaultScheduler();
 JobDetail jobDetail =
 new JobDetail("PrintInfoJob",
 Scheduler.DEFAULT_GROUP,
 PrintInfoJob.class);

 /*
 * 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());

 // Create the job listener
 JobListener jobListener =
 new SimpleJobListener("SimpleJobListener");

 // Register Listener as a nonglobal listener
 scheduler.addJobListener(jobListener);

 // Listener set on JobDetail before scheduleJob()
 jobDetail.addJobListener(jobListener.getName());

 // Register the JobDetail and Trigger
 scheduler.scheduleJob(jobDetail, trigger);

 // Start the scheduler
 scheduler.start();
 logger.info("Scheduler started at " + new Date());

 } catch (SchedulerException ex) {
 logger.error(ex);
 }
 }
}

Listing 7.4 is very similar to the code from Listing 7.3. Because the JobListener is being registered as a nonglobal listener, you have to call the addJobListener() method on the Scheduler instead of the addGlobalJobListener() method. For a nonglobal JobListener, it should be added to the Scheduler before any JobDetail that references it is added using the schedulerJob() or addJob() methods.

Next, the name of the JobListener is set on the JobDetail. Notice that the JobListener instance is not set; just the name is. This is done by calling the addJobListener() method and passing in the name. The name passed into the addJobListener() method must match the name returned from the listener getName() method. If the Scheduler can't find a listener with that name, it throws a SchedulerException.

Finally, the Scheduler is started.

The Order of the Steps for Nonglobal JobListeners Matters

The steps for adding a nonglobal JobListener must be done in order. The JobListener must be added to the Scheduler first. Then the JobListener can be set on the JobDetail object. After that, you can safely add the JobDetail to the Scheduler using the scheduleJob() method.


Listening for Trigger Events

Scheduling in the Enterprise

Getting Started with Quartz

Hello, Quartz

Scheduling Jobs

Cron Triggers and More

JobStores and Persistence

Implementing Quartz Listeners

Using Quartz Plug-Ins

Using Quartz Remotely

Using Quartz with J2EE

Clustering Quartz

Quartz Cookbook

Quartz and Web Applications

Using Quartz with Workflow

Appendix A. Quartz Configuration Reference



Quartz Job Scheduling Framework(c) Building Open Source Enterprise Applications
Quartz Job Scheduling Framework: Building Open Source Enterprise Applications
ISBN: 0131886703
EAN: 2147483647
Year: N/A
Pages: 148

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net