Example 5 - Job Misfires

This example is designed to demonstrate concepts related to trigger misfires.

The program will perform the following actions:

  • Start up the Quartz Scheduler
  • Schedule two jobs, each job will execute the every three seconds, indefinitely
  • The jobs will take ten seconds to run (preventing the execution trigger from firing every three seconds)
  • Each job has different misfire instructions
  • The program will wait 10 minutes so that the two jobs have plenty of time to run
  • Shut down the Scheduler

Running the Example

This example can be executed from the examples/example5 directory. There are two out-of-the-box methods for running this example

  • example5.sh - A UNIX/Linux shell script
  • example5.bat - A Windows Batch file

The Code

The code for this example resides in the package org.quartz.examples.example5.

The code in this example is made up of the following classes:

Class Name Description
MisfireExample The main program
StatefulDumbJob A simple job class who's execute method takes 10 seconds to run


StatefulDumbJob is a simple job that prints its execution time and then will wait for a period of time before completing.
The amount of wait time is defined by the job parameter EXECUTION_DELAY. If this job parameter is not passed in, the job will default to a wait time of 5 seconds. The job is also keep its own count of how many times it has executed using a value in its JobDataMap called NUM_EXECUTIONS. Because the class has the PersistJobDataAfterExecution annotation, the execution count is preserved between each execution.

public class StatefulDumbJob implements Job {

    public static final String NUM_EXECUTIONS = "NumExecutions";
    public static final String EXECUTION_DELAY = "ExecutionDelay";

    public StatefulDumbJob() {
    public void execute(JobExecutionContext context)
        throws JobExecutionException {
        System.err.println("---" + context.getJobDetail().getKey()
                + " executing.[" + new Date() + "]");

        JobDataMap map = context.getJobDetail().getJobDataMap();

        int executeCount = 0;
        if (map.containsKey(NUM_EXECUTIONS)) {
            executeCount = map.getInt(NUM_EXECUTIONS);

        map.put(NUM_EXECUTIONS, executeCount);

        long delay = 5000l;
        if (map.containsKey(EXECUTION_DELAY)) {
            delay = map.getLong(EXECUTION_DELAY);

        try {
        } catch (Exception ignore) {

        System.err.println("  -" + context.getJobDetail().getKey()
                + " complete (" + executeCount + ").");


The program starts by getting an instance of the Scheduler. This is done by creating a StdSchedulerFactory and then using it to create a scheduler. This will create a simple, RAM-based scheduler because no specific quartz.properties config file telling it to do otherwise is provided.

SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();

Job #1 is scheduled to run every 3 seconds indefinitely. An execution delay of 10 seconds is passed into the job:

JobDetail job = newJob(StatefulDumbJob.class)
    .withIdentity("statefulJob1", "group1")
    .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L)

SimpleTrigger trigger = newTrigger()
    .withIdentity("trigger1", "group1")

sched.scheduleJob(job, trigger);

Job #2 is scheduled to run every 3 seconds indefinitely. An execution delay of 10 seconds is passed into the job:

job = newJob(StatefulDumbJob.class)
            .withIdentity("statefulJob2", "group1")
            .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L)

        trigger = newTrigger()
            .withIdentity("trigger2", "group1")
                    .withMisfireHandlingInstructionNowWithExistingCount()) // set misfire instruction

Note: The trigger for job #2 is set with a misfire instruction that will cause it to reschedule with the existing repeat count. This policy forces quartz to refire the trigger as soon as possible. Job #1 uses the default “smart” misfire policy for simple triggers, which causes the trigger to fire at it’s next normal execution time.

The scheduler is then started.


To let the program have an opportunity to run the job, we then sleep for ten minutes (600 seconds)

Thread.sleep(600L * 1000L);

Finally, we will gracefully shutdown the scheduler:


Note: passing true into the shutdown message tells the Quartz Scheduler to wait until all jobs have completed running before returning from the method call.