Monday, January 10, 2011

Schedule Jobs in Java using Quartz (Java Job scheduling tutorial)

How to schedule Jobs in Java using Quartz (Java Job scheduling tutorial)


This tutorial is intended for Users who are looking to automate job scheduling in Java using Quartz. For example, if you would like to run a particular Java program at a particular point of time and date (and at regular frequencies) automatically, you can use the Quartz API to achieve this.

I will provide a simple example that covers the basics of the Quartz API to perform the scheduling.

Quartz API has the following basic objects.

SchedulerFactory
Scheduler
JobDetail
Trigger.

If you are using Apache Maven,  just add the following dependency in your pom.xml

      
                           org.quartz-scheduler
                           quartz
                           1.8.4
      
If you are not using Maven(or don’t know what Maven is), download the Quartz API from www.quartzscheduler.org and include it in your application’s build path. Btw, I strongly recommend you to start using Maven for your projects if you haven’t already. Off topic, but it is a wonderful dependency management tool (among various other features)

The concept is that you create a Scheduler object using the SchedulerFactory (Factory pattern if you know what I mean. I will show the related code below). And then you create a JobDetail object(by assigning the job a name and a group). Finally, you create a Trigger object that tells the scheduler on when to run the Job.

The trigger schedule can be set using CRON. If you are not sure what CRON is, it is just a expression (which is essentially a string) that tells the second/minute/hour/day of month/month/day of week/year in a regex format. The first 6 fields are mandatory and the last one(year) is optional.

A cron expression is a string comprised of 6 or 7 fields(explained above) separated by white space. Fields can contain any of the allowed values, along with various combinations of the allowed special characters for that field.

Just look at the following expression.

10 * * * * ?

This means that on the 10th second(1st field - 10)of every minute(2nd field - *) of every hour (3rd field - *)of every day(4th field - *)  of every month (5th field - *), the job will be run. The 6th field was marked as ? as there is no specific useful value for that. I mean if we are running the job everyday, there is no point in mentioning it to run on Sun/Mon/Tue etc. Also, if in another CRON expression we want to run on the 15th of every month and we don’t care what day of the week it is (Sun/Mon etc.), we can mark the 6th field as ?. I think you get the idea. The 7th field is the year, which is an optional field, which I haven’t used in the above expression. Another example:

0 0 0 1 1 ? *

On the 0th second of the 0th minute of the 0th hour of the 1st day of the 1st month of each year, do something. Like partying for a new year?

Ok, enough of CRON. There are a lot of other ways to use/customize CRON, which you can read in the related links at the end of the post.  Now back to the Quartz scheduler program.

Create a new Java class named QuartzTesting. This has to implement the Job interface, and thereby the execute method. Once the below program is run, the code in the execute method will be invoked at the regular frequency specified as per the CRON expression.
package com.abc.quartz.testing;

import java.text.ParseException;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzTesting implements Job{

                /** The sched fact. */
                private static SchedulerFactory schedFact = new StdSchedulerFactory();
               
                /** The sched. */
                private static Scheduler sched;
               
                static
                {
                                try {
                                                sched = schedFact.getScheduler();
                                } catch (SchedulerException e) {
                                                System.out.println("Exception in static block of QuartzTesting class, Exiting the program " +e);
                                                System.exit(-1);
                                }
                }

                /**
                 * @param args
                 */
                public static void main(String[] args) {
                               
                                try {
                                                //start the scheduler
                                                sched.start();

                                                //Create the JobDetail object and the CronTrigger
                                                JobDetail jobDetail = new JobDetail("Name",
                                                                                "Group", QuartzTesting.class);

                                                CronTrigger trigger = new CronTrigger("Name", "Group");
                                               
                                                //Set the CRON expression as per the desired frequency
                                                trigger.setCronExpression("*/10 * * * * ?");
                                               
                                                //schedule the job
                                                sched.scheduleJob(jobDetail, trigger);
                                } catch (SchedulerException e) {
                                                e.printStackTrace();
                                                System.exit(-1);
                                } catch (ParseException e) {
                                                e.printStackTrace();
                                                System.exit(-1);
                                }

                }

                public void execute(JobExecutionContext cntxt) throws JobExecutionException {

                                try {
                                                                //insert the code here that needs to be performed at the intervals scheduled using CRON trigger
                                                                //like making a Webservice call or running a report etc.
                                                                System.out.println("Running the code in the execute method");
                                                }
                                                                catch (Exception ex) {
                                                                                System.out.println(
                                                                                                                "Exception occured in execute method " +ex);
                                                                }
                                               
                                                }
}
Now, if you compile and run the above program, you will see a Java process running in your task manager. You should the Sysout at the intervals specified as per CRON (on the 10th  second of each minute in the above example. Please note that you see Sysouts every one minute and not every 10 seconds. If you want Sysouts every 10 seconds change the CRON expression to */10 * * * * ? )

If you were wondering what the name and Group are for the JobDetail/Trigger objects, they are used to identify the jobs if you have multiple jobs/triggers. In those multiple job scenarios, you can refer to the particular jobs using their names. Something like,

      //Delete if the job already exists and then schedule the job
                sched.deleteJob(“Sending Job”, “Send Group”);
References/Useful links:

  1. www.quartzscheduler.org
  2. http://oreilly.com/pub/a/java/archive/quartz.html?page=1
  3. http://www.quartz-scheduler.org/docs/tutorials/crontrigger.html

Tags: Java Job scheduling Quartz CRON trigger frequency timer regular intervals example basic tutorial

12 comments :

  1. Its really Good... Post some blogs regarding maven script. Very nice. Thanks...

    ReplyDelete
    Replies
    1. Thanks S.Sakthivel. I will try to add more posts related to Maven script

      Delete
  2. Thanks. Nice info. It really helped me.

    ReplyDelete
  3. awesome dude.....pls post more.....

    ReplyDelete
  4. check out also http://job-scheduler.javaplanner.com/

    ReplyDelete
  5. Nice work. groupid and artifactid, i should be capital groupId and artifactId

    ReplyDelete
  6. Excellent work bro.

    ReplyDelete
  7. It is possible to run cron run everyday but not in a Sunday and Saturday ?

    ReplyDelete
    Replies
    1. Try 0 0 * * 1-5
      The first fields are minutes and hours. In this case the command will run at midnight. The stars mean: for every day of the month, and for every month. The 1 to 5 specify the days. monday to friday. 6=saturday 0=sunday.

      Delete
  8. It's really helpful example , but what about if I'm not using maven and make a cron -tab in normal java class file ?

    Is there any jar required while I'm using normal class file?

    ReplyDelete
    Replies
    1. You can download the quartz jar files from the official quartz website

      Delete