Home | FAQ | Contact me

Quartz!

This demonstrates using the Quartz job control software. There are three classes jammed into this sample code. Here, we have a job that is executed, but we want to override the Quartz JobDetail class to modifying a field of this job that goes beyond the fields of JobDetail. The field added is totally nonsensical (a lion's name).

We can set the lion's name and a predicate action when creating a job (to demonstrate overriding JobDetail with our own necessities). If we were creating many jobs, presumably one per lion, there would be a lot of variation in this private data—hence the exercise.

Inside this code

In terms of beginning Java samples you have:

  • The use of the Quartz job control mechanism including jobs, details, triggers and simple scheduling.
  • Overriding a class (JobDetail is overridden by RussJobDetail).
  • Some use of Java 5 generics.
Eclipse tip: Stopping JSP validation!

When creating a project (or, especially, projects) from repository sources (source code already in Subversion or CVS) with JSP sources, start by choosing Window->Preferences...->Validation and click Suspend all validators.

This will keep Eclipse from going seriously out to lunch while you're building the project or projects. JSP validation can be very time-consuming and may even hang Eclipse (on Linux, at least).


RussScheduler.java:
package com.etretatlogiciels.samples.quartz;

import java.util.Date;

import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.SchedulerException;

public class RussScheduler
{
  public static void main( String[] args )
  {
    try
    {
      Scheduler     scheduler = StdSchedulerFactory.getDefaultScheduler();
      RussJobDetail jobDetail = new RussJobDetail( "Russ' world",
                                         null,
                                         RussJob.class );

      // Trigger trigger = new SimpleTrigger( "Russ' world", "Russ' world" );
      Trigger trigger = TriggerUtils.makeSecondlyTrigger( 1 );
      trigger.setStartTime( new Date() );
      trigger.setName( "Russ' Trigger" );

      jobDetail.setLionName( "Snagglepus" );
      jobDetail.setVariant( "will exit, stage left!" );
      scheduler.start();
      scheduler.scheduleJob( jobDetail, trigger );
    }
    catch( SchedulerException e )
    {
      e.printStackTrace();
    }
  }
}
RussJob.java:
package com.etretatlogiciels.samples.quartz;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.quartz.Job;
import org.quartz.JobExecutionContext;

/**
 * The "private" detail added is a lion's name and a variant predicate that can
 * be appended to the former to make a sentence.
 */
public class RussJob implements Job
{
  //private static final String  DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
  private static final String  DATE_FORMAT_NOW = "HH:mm:ss";

  public void execute ( JobExecutionContext context )
  {
    RussJobDetail jobDetail    = ( RussJobDetail ) context.getJobDetail();
    String        announcement = jobDetail.getLionName()
                                 + " "
                                 + jobDetail.getVariant();

    Calendar          cal = Calendar.getInstance();
    SimpleDateFormat  sdf = new SimpleDateFormat( DATE_FORMAT_NOW );
    String            now = sdf.format( cal.getTime() );
    System.out.print( "\nIn Russ' world, at "
                      + now
                      + ", "
                      + announcement );
  }
}
RussJobDetail.java:
package com.etretatlogiciels.samples.quartz;

import org.quartz.JobDetail;

/**
 * The point of this class is to extend Quartz' JobDetail.
 */
public class RussJobDetail extends JobDetail
{
  static final long  serialVersionUID = 0;

  private String  lionName = null;
  private String  variant  = null;

  public RussJobDetail( String name, String group, Class< RussJob > jobClass )
  {
    super( name, group, jobClass );
  }

  public RussJobDetail( String           name,
                   String           group,
                   Class< RussJob > jobClass,
                   boolean          volatility,
                   boolean          durability,
                   boolean          recover )
  {
    super( name, group, jobClass, volatility, durability, recover );
  }

  public String getLionName()                { return this.lionName; }
  public void setLionName( String lionName ) { this.lionName = lionName; }
  public String getVariant()                 { return this.variant; }
  public void setVariant( String variant )   { this.variant = variant; }
}

Console output

The output continues infinitely until you interrupt it. Each output line is a job scheduled and executed. In red you see the Quartz initialization as is allowed through to the console by Eclipse.

INFO: Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl Jun 6, 2009 8:31:05 PM org.quartz.core.QuartzScheduler INFO: Quartz Scheduler v.1.6.4 created. Jun 6, 2009 8:31:05 PM org.quartz.simpl.RAMJobStore initialize INFO: RAMJobStore initialized. Jun 6, 2009 8:31:05 PM org.quartz.impl.StdSchedulerFactory instantiate INFO: Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' Jun 6, 2009 8:31:05 PM org.quartz.impl.StdSchedulerFactory instantiate INFO: Quartz scheduler version: 1.6.4 Jun 6, 2009 8:31:05 PM org.quartz.core.QuartzScheduler start INFO: Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. In Russ' world, at 20:31:05, Snagglepuss will exit, stage left! In Russ' world, at 20:31:06, Snagglepuss will exit, stage left! In Russ' world, at 20:31:07, Snagglepuss will exit, stage left! . . .