ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

What Is Quartz
Pages: 1, 2, 3, 4, 5

Job Management and Storage

Once Jobs have been scheduled, the Scheduler needs to remember and keep track of the Jobs and the times to execute them. It wouldn't be very useful if your Job is called 30 minutes late or even 30 seconds early. In fact, Job execution needs to be very exact and prompt about calling the execute() methods on the scheduled jobs. Job storage and management is done through a concept Quartz refers to as a JobStore.

Available JobStores

The Quartz framework provides two basic types of JobStores. The first type, which utilizes ordinary memory (RAM) to persist Scheduler information, is called RAMJobStore. This type of JobStore is the easiest to configure and get up and running. For many applications, this JobStore will be sufficient. However, since the Scheduler information is stored in the memory assigned to the JVM, when the application is stopped, all knowledge of the schedule is lost. If you need to persist schedule information between restarts, then you're going to need the second type of JobStore.

The second type of JobStore actually comes with two different implementations in the framework, but both are commonly referred to as JDBC JobStores. Both JDBC JobStores use a JDBC driver and require a backing from a relational database to persist the scheduler information. The two types differ in whether or not you want to control the database transactions or relinquish control to an application container such as BEA's WebLogic or JBoss. (This is similar to the difference between Bean Managed Transactions or Container Managed Transactions from the J2EE world.)

The two JDBC JobStores are:

  • JobStoreTX: used when you want to control transactions or when you're operating in a nonapplication server environment

  • JobStoreCMT: used when operating within an application server environment and you want the container to manage the transactions

The JDBC JobStores are designed for users who require the Scheduler to maintain scheduling information, even after a shutdown and startup.

Jobs and Triggers

Jobs are only half the equation. The designers of Quartz made a design choice to separate the Job from the schedule. A Trigger in Quartz is used to tell the Scheduler when a Job should be triggered (or fired). The framework comes with a handful of Trigger types, but the two most commonly used are the SimpleTrigger and the CronTrigger.

The SimpleTrigger is designed for when you need a simple firing schedule. Typically, if you need to fire a Job at a given time and repeat (n) number of times, possibly waiting (m) seconds between firings, then the SimpleTrigger is for you. If on the other hand, you have a much more complicated scheduling need for your Job, then the CronTrigger will probably be required.

The CronTrigger is based on Calendar-like schedules. When you need a Job executed every day at 10:30 a.m., except on Saturdays and Sundays, then a CronTrigger should be used. As the name implies, the CronTrigger is based on the Unix cron expression. As an example, the following Quartz cron expression would execute a Job at 10:15 a.m. every day, Monday through Friday.

0 15 10 ? * MON-FRI

and this expression

0 15 10 ? * 6L 2002-2005

fires at 10:15 a.m. on the last Friday of every month during the years 2002, 2003, 2004, and 2005.

You can't do this with the SimpleTrigger. Either can be used for your Jobs. Which one just depends on your schedule needs.

Scheduling a Job

So, let's take this discussion into the practical realm by looking at an example Job. Suppose that you manage a department that needs to be notified by email whenever a client stores a file on its FTP site. Our Job will FTP to a remote server and download any files found there. It will then send an email containing the number of files found and downloaded. This Job would be handy to prevent someone from having to manually performing this task during the day, not even considering during the night. We can set this Job up to check every 60 seconds and to run indefinitely, 24 hours a day, seven days a week. This is a perfect use of the Quartz framework!

The first step is to create the Job class that will perform the FTP and Email logic. The following Example shows our Quartz Job class, which implements the org.quartz.Job interface.

Example 2. A Quartz Job that downloads files from a FTP site and sends an Email

public class ScanFTPSiteJob implements Job {
    private static Log logger = LogFactory.getLog(ScanFTPSiteJob.class);

     * Called the scheduler framework at the right time
    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        JobDataMap jobDataMap = context.getJobDataMap();

        try {
            // Check the ftp site for files
            File[] files = JobUtil.checkForFiles(jobDataMap);

            JobUtil.sendEmail(jobDataMap, files);
        } catch (Exception ex) {
            throw new JobExecutionException(ex.getMessage());

We intentionally kept the ScanFTPSiteJob very simple. We created a utility class for this example called JobUtil. That's not part of Quartz, but it makes sense to build your own library of utilities that various Jobs can reuse. We could have just as easily put all of that code inside the Job class and the Quartz Scheduler would have been just as happy, but reuse doesn't stop just because we're using Quartz.

The parameters that the JobUtil.checkForFiles() and JobUtil.sendEmail() methods use come from the JobDataMap object, which is a Quartz-created object. An instance of it is created for every Job execution and it is a way to pass configuration parameters to your Job class.

The implementation of the JobUtil is not shown here, but we could very easily use the Commons Net from Jakarta to implement both the FTP and Email functionality.

Pages: 1, 2, 3, 4, 5

Next Pagearrow