Quartz Simple Example

Quartz schedular framework can be used to schedule jobs. This post explains how we can use it with a simple example.

We need the below jars
1) c3p0-0.9.1.1.jar
2) log4j-1.2.16.jar
3) quartz-2.2.3.jar
4) quartz-jobs-2.2.3.jar
5) slf4j-api-1.7.7.jar
6) slf4j-log4j12-1.7.7.jar

log4j.xml file in the classpath with the below configurations

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

 <appender name="default" class="org.apache.log4j.ConsoleAppender">
 <param name="target" value="System.out"/>
 <layout class="org.apache.log4j.PatternLayout">
 <param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss.SSS aa} %t [%c]%n%m%n%n"/>
 </layout>
 </appender>


 <logger name="org.quartz">
 <level value="info" />
 </logger>

 <root>
 <level value="info" />
 <appender-ref ref="default" />
 </root>

 
</log4j:configuration>

To schedule a job we need an instance of Scheduler, which can be obtained as shown below
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler schedular = schedulerFactory.getScheduler();

In the above snippet, we create an instance of StdSchedulerFactory provided by Quartz framework and assigned to SchedulerFactory interface.
From the interface we create an instance of Scheduler class by calling getScheduler method.

Next we have to create the job which will be scheduled to be executed by implementing the Job interface as shown below

Job Code


package package1;

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

public class HelloJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Hello Job is executing.");
    }
}

As shown in the above code, we create a job class named HelloJob implementing the interface Job.

Next we create a JobDetail. An instance of JobDetail is used to provide job parameters and configuration information to an instance of job, which will be accessible via JobExecutionContext as shown below


JobBuilder jobBuilder = JobBuilder.newJob(HelloJob.class);
jobBuilder.withDescription("Job Description").withIdentity("jobDetail1", "group1");
        
JobDetail jobDetail = jobBuilder.build();

We take the help of utility class named JobBuilder to create an instance of JobDetail with required parameters and configuration information.

In the above code snippet we create an instance of JobDetail. We give an identity “jobDetail1” to the instance of JobDetail, associate it to a group named “group1”, and provide description for other developers to understand the purpose of creating the job detail.

Job interface is used to define the task to be done.

JobDetail class is used to define the parameters and configurations that will be passed to each instance of job.

Both class helps in separating “what to be done” from “On what to be done”.

Next we create a schedule for the job instance as shown below
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(10);

In the above code snippet we have created a schedule, the schedule is to repeat the JobDetail identified by “jobDetail1” to be run every second for total of 10 times.

Next we build a trigger that will follow the schedule and trigger the job, as shown below


TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withSchedule(simpleScheduleBuilder).withDescription("Trigger Description").withIdentity("trigger1", "group1").startNow();
        
Trigger trigger = triggerBuilder.build();

In the above code snippet, we create a trigger give it an identity and assign it to a group. We assign the schedule, that we want the job to follow, which is in this case is simpleScheduleBuilder that we created earlier.

Now we provide both the JobDetail and trigger to the schedular as shown below
schedular.scheduleJob(jobDetail, trigger);

Next we start schedular as shown below
schedular.start();

Once started, we can get the status of the schedule with the help of TriggerState, as shown below


TriggerState triggerState = schedular.getTriggerState(trigger.getKey());
        
while(triggerState != TriggerState.NONE) {
    triggerState = schedular.getTriggerState(trigger.getKey());
}

This code will run the loop untill the state changes to NONE.

As long as TriggerState is not in NONE, means the scheduler is in one of the following states

  1. BLOCKED
  2. COMPLETE
  3. ERROR
  4. NORMAL
  5. PAUSED

Next we shutdown the schedular as shown below
schedular.shutdown(true);

We pass boolean true as a parameter indicating the schedular to wait for the running jobs to complete.

Below is complete code

Main code


package package1;

import java.io.IOException;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzDemo1 {
    public static void main(String[] args) throws SchedulerException, IOException {
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler schedular = schedulerFactory.getScheduler();
        
        JobBuilder jobBuilder = JobBuilder.newJob(HelloJob.class);
        jobBuilder.withDescription("Job Description").withIdentity("jobDetail1", "group1");
        
        JobDetail jobDetail = jobBuilder.build();
        
        SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(10);
        
        TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
        triggerBuilder.withSchedule(simpleScheduleBuilder).withDescription("Trigger Description").withIdentity("trigger1", "group1").startNow();
        
        Trigger trigger = triggerBuilder.build();
        
        schedular.scheduleJob(jobDetail, trigger);
        
        schedular.start();
        TriggerState triggerState = schedular.getTriggerState(trigger.getKey());
        
        while(triggerState != TriggerState.NONE) {
            triggerState = schedular.getTriggerState(trigger.getKey());
        }
        
        schedular.shutdown(true);
    }
}

Output

[INFO] 18 Mar 12:32:24.427 PM main [org.quartz.impl.StdSchedulerFactory]
Using default implementation for ThreadExecutor

[INFO] 18 Mar 12:32:24.427 PM main [org.quartz.simpl.SimpleThreadPool]
Job execution threads will use class loader of thread: main

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.core.SchedulerSignalerImpl]
Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.core.QuartzScheduler]
Quartz Scheduler v.2.2.3 created.

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.simpl.RAMJobStore]
RAMJobStore initialized.

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.core.QuartzScheduler]
Scheduler meta-data: Quartz Scheduler (v2.2.3) ‘DefaultQuartzScheduler’ with instanceId ‘NON_CLUSTERED’
Scheduler class: ‘org.quartz.core.QuartzScheduler’ – running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool ‘org.quartz.simpl.SimpleThreadPool’ – with 10 threads.
Using job-store ‘org.quartz.simpl.RAMJobStore’ – which does not support persistence. and is not clustered.

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler ‘DefaultQuartzScheduler’ initialized from default resource file in Quartz package: ‘quartz.properties’

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler version: 2.2.3

[INFO] 18 Mar 12:32:24.442 PM main [org.quartz.core.QuartzScheduler]
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.

Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
Hello Job is executing.
[INFO] 18 Mar 12:32:33.443 PM main [org.quartz.core.QuartzScheduler]
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.

[INFO] 18 Mar 12:32:33.443 PM main [org.quartz.core.QuartzScheduler]
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.

[INFO] 18 Mar 12:32:33.950 PM main [org.quartz.core.QuartzScheduler]
Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s