Quartz – Enterprise Open Source Job Scheduler – Part1

quartz scheduler

In this post, we will discuss about the java job scheduler called “Quartz”. In a brief introduction, quartz is providing job scheduling infrastructure to integrate with stand alone applications to large enterprise applications, to perform the defined tasks on scheduling basis.

                  The use case to use Quartz is, any task which is performing on a regular interval of time. For example, in an e-commerce application, if you have a job to process the inventory feed on a daily basis, then we can create a Quartz job to trigger the task.

                  Quartz can be integrated as part of any standalone application, any servlet container, via RMI or as a cluster of stand-alone programs (with load-balance and fail-over capabilities). We can create persistence jobs or in-memory jobs.

                  Now, we will see how we can create a simple job to send emails to all users on daily basis. Before that, we will see how to setup development environment to use Quartz.

  1. As a first step, download the most recent stable release from http://www.quartz-scheduler.org/downloads/ . In this example, I am using Quartz 2.1.7 .

  2. After downloading, unpack the zip file. The unpacked Quartz package contains number of jar files, located under root directory. The main Quartz library is named quartz-all-2.1.7.jar. This jar includes all the Quartz features.

  3. Keep the quartz-all-2.1.7.jar into our application class path.

  4. Keep all the dependent jar files (slf4j-log4j12-1.6.1.jar,slf4j-api-1.6.1.jar,log4j-1.2.16.jar,javax.transaction.jar,c3p0-0.9.1.1.jar) into the class path.

  5. Keep quartz.properties file in class path.

All the configuration details will be available under quartz.properties file. So, the Quartz scheduler will take the configuration details from here.

                Now, we will create a stand alone Java application to demonstrate the Quartz. The source code is available here https://github.com/2013techsmarts/Quartz_Proj

The below sample code creates a scheduler instance.

package com.smarttechies.scheduler;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
public class MailScheduler {
/**
* @param args
*/
public static void main(String[] args) {
try {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
scheduler.start();
} catch (SchedulerException se) {
   se.printStackTrace();
   }
 }
}

We are getting scheduler instance by calling org.quartz.impl.StdSchedulerFactory.getDefaultScheduler method. We are starting the scheduler by calling the start method. When we start the scheduler, it will get the configuration from the quartz.properties available in the class path.

The log will depict some of the scheduler details.

2013-04-19 22:18:42 INFO  StdSchedulerFactory:1175 - Using default implementation for ThreadExecutor
2013-04-19 22:18:42 INFO  SchedulerSignalerImpl:61 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2013-04-19 22:18:42 INFO  QuartzScheduler:243 - Quartz Scheduler v.2.1.7 created.
2013-04-19 22:18:42 INFO  RAMJobStore:154 - <strong>RAMJobStore</strong> initialized.
2013-04-19 22:18:42 INFO  QuartzScheduler:268 - Scheduler meta-data: Quartz Scheduler (v2.1.7) '<strong>MailScheduler</strong>' 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 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2013-04-19 22:18:42 INFO  StdSchedulerFactory:1324 - Quartz scheduler 'MailScheduler' initialized from default file in current working dir: 'quartz.properties'
2013-04-19 22:18:42 INFO  StdSchedulerFactory:1328 - Quartz scheduler version: 2.1.7
2013-04-19 22:18:42 INFO  QuartzScheduler:534 - Scheduler MailScheduler_$_NON_CLUSTERED started.

From the log we can  understand that, scheduler is using quartz.properties and we have configured in-memory scheduler. So, it is using RAM job store.

Now, we create a job and trigger to run the job on every minute. To create a job, we need to implement org.quartz.Job interface and provide implementation to the execute method.

The sample MailSenderJob code is given below.

package com.smarttechies.job;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MailSenderJob implements Job{
Logger log = Logger.getLogger(MailSenderJob.class);
@Override
public void execute(JobExecutionContext pArg0) throws JobExecutionException {
log.info("The mail sender job triggerd");
//From here call the mail sender service
  }
 }

Now, in the MailScheduler code which was written earlier, we need to configure the job and the trigger. After the change, the MailScheduler code will be as shown below.

package com.smarttechies.scheduler;
import java.text.ParseException;
import org.quartz.CronExpression;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import com.smarttechies.job.MailSenderJob;
public class MailScheduler {
/**
 * @param args
 * @throws ParseException
*/
public static void main(String[] args) throws ParseException {
try {
  SchedulerFactory sf = new StdSchedulerFactory();
  Scheduler scheduler = sf.getScheduler();
  //Tie the MailSenderJob to scheduler
  JobDetailImpl jobDetail = new JobDetailImpl();
  jobDetail.setGroup("group1");
  JobKey jobKey = new JobKey("job1");
  jobDetail.setKey(jobKey);
  jobDetail.setJobClass(MailSenderJob.class);
  //create a trigger and tie it to the job
  // Trigger the job to run on every minute
  CronExpression cronExpression = new CronExpression("0 0/1 * 1/1 * ? *");
  CronTriggerImpl cronTrigger = new CronTriggerImpl();
  cronTrigger.setName("mail trigger");
  cronTrigger.setCronExpression(cronExpression);
  //Tie the job and the trigger to the scheduler
  scheduler.scheduleJob(jobDetail, cronTrigger);
  scheduler.start();
} catch (SchedulerException se) {
  se.printStackTrace();
    }
  }
}

The above scheduler will trigger the job for every minute.The log indicates the same.

2013-04-20 11:26:11 INFO  StdSchedulerFactory:1175 - Using default implementation for ThreadExecutor
2013-04-20 11:26:11 INFO  SchedulerSignalerImpl:61 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2013-04-20 11:26:11 INFO  QuartzScheduler:243 - Quartz Scheduler v.2.1.7 created.
2013-04-20 11:26:11 INFO  RAMJobStore:154 - RAMJobStore initialized.
2013-04-20 11:26:11 INFO  QuartzScheduler:268 - Scheduler meta-data: Quartz Scheduler (v2.1.7) 'MailScheduler' 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 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2013-04-20 11:26:11 INFO  StdSchedulerFactory:1324 - Quartz scheduler 'MailScheduler' initialized from default file in current working dir: 'quartz.properties'
2013-04-20 11:26:11 INFO  StdSchedulerFactory:1328 - Quartz scheduler version: 2.1.7
2013-04-20 11:26:11 INFO  QuartzScheduler:534 - Scheduler MailScheduler_$_NON_CLUSTERED started.
2013-04-20 11:27:00 INFO  <strong>MailSenderJob:14 - The mail sender job triggerd</strong>

To stop the scheduler, we need to call shutDown method on scheduler.

The approach we followed in this article to configure the job and trigger is programmatic.  In the coming post we will see, how we can improve the same code by moving the job and trigger configurations to XML file by using quartz plugins.

Advertisements

I am Siva Prasad Rao Janapati. Working as a software developer. Has hands on experience on ATG Commerce(DAS/DPS/DCS), Mozu commerce, Broadleaf Commerce, Java, JEE, Spring, Play, JPA, Hibernate, Velocity, JMS, Jboss, Weblogic,Tomcat, Jetty, Apache, Apache Solr, Spring Batch, JQuery, NodeJS, SOAP, REST, MySQL, Oracle, Mongo DB, Memcached, HazelCast, Git, SVN, CVS, Ant, Maven, Gradle, Amazon Web services, Rackspace, Quartz, JMeter, Junit, Open NLP, Facebook Graph,Twitter4J, YouTube Gdata, Bazzarvoice,Yotpo, 4-Tell, Alatest, Shopzilla, Linkshare. I have hands on experience on open sources and commercial technologies.

Tagged with: , ,
Posted in Quartz Scheduler, Scheduler

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

DZone

DZone MVB

Java Code Geeks
Java Code Geeks
%d bloggers like this: