//Spring Quartz Tutorial

Spring Quartz Tutorial

In this post I’ll show you how to use Quartz scheduling with a Spring application. Quartz can be easily integrated with Spring to invoke schedule tasks that call your existing business logic. One of the things I really like about Springs support for Quartz is that you don’t have to write any Quartz specific code or amend your existing code to use Quartz scheduling. You simply configure Quartz alongside your existing bean definitions and point it at the logic that you’d like to invoke.

Tech Stack

Our Spring/Quartz example will be built as a stand alone Java application using the following.
  • Spring 3.1
  • Maven
  • Quartz 1.6

It is assumed that readers have a basic knowledge of Spring and Maven. To help you get an example running quickly I’ll add a link to the full source code at the bottom of this post. Once you download the Maven project simply import it into Eclipse and run a Maven build.

Creating a Simple Project

We’ll start off by creating a very simple Spring project like the one shown in figure 1.0 below.

Figure 1.0 – Project Structure

The main project components are described below.
  • src/main/java folder – this folder structure will contain our Java source. We’ll have just 2 classes – TestsService.java and RunTest.java, both of which are defined below.
  • src/main/resources folder – this folder will contain our Spring and log4J configuration files.

Creating a Simple Service

We’ll start off by creating a class containing a simple service method that we’ll invoke with Quartz. The testServiceMethod method is very simple indeed and just logs out the current time – this will allow us to see exactly when the method is invoked by Quartz. The important thing to note is that this code is not coupled to Quartz in any way – it’s a simple POJO. This means that you can integrate Quartz with your application and configure it to invoke existing code without making any changes to the code whatsoever. The service class is defined below.
package com.blog.samples.quartz;
import java.util.Date; 
import org.apache.log4j.Logger; 
import org.springframework.stereotype.Service;

public class TestService 
  private static final Logger logger_c = Logger.getLogger(TestService.class);

  public void testServiceMethod() 
    Date date = new Date(); 
    logger_c.debug("test service method invoked: " + date.toString()); 

Spring/ Quartz Configuration

Next we’ll look at the Spring configuration and setting up Quartz in particular. I’ve explained the various bean configurations with comments below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
           Our test service bean  
     <bean id="testService" class="com.blog.samples.quartz.TestService" />
         Job Detail bean configuration specifies the target object (our service object defined above) 
         and the method we want to invoke on that object (testServiceMethod). The concurrent property 
         specifies whether or not multiple instances of this job can be invoked concurrently 
     <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
       <property name="targetObject" ref="testService" />
       <property name="targetMethod" value="testServiceMethod" />
       <property name="concurrent" value="false" />
         The cron trigger bean allows us to specify the job that we want to invoke (jobDetail above) 
         and a cron expression that defines when the job should be invoked. My configuration below 
         will be invoked every 10 seconds 
     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
       <property name="jobDetail" ref="jobDetail" />
       <property name="cronExpression" value="0,10,20,30,40,50 * * * * ?" />
         The SchedulerFactoryBean takes a list of cron triggers - our example has just one 
         cron trigger but larger enterprise applications will typically have a number of different 
         cron trigger for different jobs. The quartz properties property allows you to specify 
        some specific quartz properties. In our simple example we tell Quartz not to check for updates 
     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
       <property name="triggers">
            <ref bean="cronTrigger" />
      <property name="quartzProperties">
            <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>

Creating a Test Class

Next we’ll create a test class to run our Quartz application. This is a simple class with a main method that loads the spring application context from the classpath. Once the application context is loaded we sleep the thread for 100 seconds so as to allow the Quartz scheduler to run and invoke our service method. Our Quartz cron definition was set up to run every 10 seconds so we should see our service method called 10 times before our application context is closed and the application shuts down. Our test class is defined below.
package com.blog.samples.quartz;
import org.apache.log4j.Logger; 
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class RunTest 
  private static final Logger logger_c = Logger.getLogger(RunTest.class);

  public static void main (String [] args) 
    logger_c.debug("loading spring application context"); 
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml");

      /* sleep thread */ 
    catch (InterruptedException ex) 

    /* close down spring application context */ 

Running the Application

When we run the main method above we see the following output to the console.You’ll see that our service method is invoked by Quartz exactly every 10 seconds as expected.
DEBUG: [Sep-02 13:27:58,334] samples.quartz.RunTest - loading spring application context  
INFO : [Sep-02 13:27:58,578] context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@314c194d: startup date [Sun Sep 02 13:27:58 BST 2012]; root of context hierarchy  
INFO : [Sep-02 13:27:59,552] quartz.core.QuartzScheduler - Quartz Scheduler v.1.6.0 created.  
INFO : [Sep-02 13:27:59,556] quartz.simpl.RAMJobStore - RAMJobStore initialized.  
INFO : [Sep-02 13:27:59,556] quartz.impl.StdSchedulerFactory - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.  
INFO : [Sep-02 13:27:59,556] quartz.impl.StdSchedulerFactory - Quartz scheduler version: 1.6.0  
INFO : [Sep-02 13:27:59,560] quartz.core.QuartzScheduler - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@5773ec72  
INFO : [Sep-02 13:27:59,578] context.support.DefaultLifecycleProcessor - Starting beans in phase 2147483647  
INFO : [Sep-02 13:27:59,579] scheduling.quartz.SchedulerFactoryBean - Starting Quartz Scheduler now  
INFO : [Sep-02 13:27:59,579] quartz.core.QuartzScheduler - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.  
DEBUG: [Sep-02 13:28:00,048] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:00 BST 2012  
DEBUG: [Sep-02 13:28:10,024] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:10 BST 2012  
DEBUG: [Sep-02 13:28:20,018] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:20 BST 2012  
DEBUG: [Sep-02 13:28:30,014] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:30 BST 2012  
DEBUG: [Sep-02 13:28:40,021] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:40 BST 2012  
DEBUG: [Sep-02 13:28:50,013] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:28:50 BST 2012  
DEBUG: [Sep-02 13:29:00,020] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:29:00 BST 2012  
DEBUG: [Sep-02 13:29:10,020] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:29:10 BST 2012  
DEBUG: [Sep-02 13:29:20,027] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:29:20 BST 2012  
DEBUG: [Sep-02 13:29:30,018] samples.quartz.TestService - test service method invoked: Sun Sep 02 13:29:30 BST 2012  
INFO : [Sep-02 13:29:39,583] context.support.DefaultLifecycleProcessor - Stopping beans in phase 2147483647  
INFO : [Sep-02 13:29:39,587] quartz.core.QuartzScheduler - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.  
DEBUG: [Sep-02 13:29:39,590] samples.quartz.RunTest - exiting...

Wrapping Up

The sample code in this tutorial is very simple indeed, but should provide you with the information required to get Quartz scheduling up and running within a Spring application. If you want to run this tutorial locally you can grab the full source code here https://docs.google.com/open?id=0B_SZOyniHfc1M0FDeW4tT0J1SWs.
By |2019-02-21T07:23:22+00:00September 2nd, 2012|Spring|13 Comments


  1. Mario Guerrero 11th September 2012 at 1:58 pm - Reply


    It is posible deploy a spring-quartz project in a cluster mode?
    The cluster has many nodes and each node is in a different location (is not possible to synchronize the clocks of the machines).


  2. Brian 11th September 2012 at 2:42 pm - Reply

    Yes it is possible to set Quartz up in a cluster. I actually did this a few weeks ago in work. We had to deploy our solution onto a WebSphere cluster and to ensure that each Quartz job was only invoked on one node at any given time, I used a JDBCJobStore instead of the standard in memory job store(RAMJobStore). This means that the invocation of Quartz jobs are managed centrally in the database as opposed to be being managed in memory by each node in the cluster.

    In very simple terms, Quartz cluster support works by placing a lock on a Job in the database when the first node attempts to process that job. Subsequent nodes are not allowed to invoke the same the job as it is already being processed. This simple mechanism ensures that only one node in your cluster processes a scheduled task. This is the kind of behaviour we wanted in a cluster but I'm sure that other approaches can be taken. If you'd like I can put together a quick post on setting up Quartz in a cluster?

  3. Brian 23rd September 2012 at 12:10 pm - Reply
  4. pzak 15th October 2012 at 8:06 am - Reply

    Hi Brian,

    I have Quartz clustered with 2 nodes, running on 2 different machines.
    Both running as standalone programs.

    I'm using JDBCJobStore.

    I have a job scheduled to run every 20 mins. (0 0/20 * * * ?) with cron trigger.

    Surprisingly, The job gets triggered twice given time interval. Once on each node, randomly

    It has run twice at these times yesterday. 8:20, 10:40, 14:20,20:00, 20:40.

    Please let me know, is there anything wrong?

  5. Sridhar Sarnobat 28th December 2012 at 4:32 am - Reply

    Thank you for providing this sample. Most other Spring Quartz samples are way too complicated for me.

  6. Hima P 3rd January 2013 at 1:32 pm - Reply

    thank u so much for providing these examples…..

  7. Aemro B. 12th January 2013 at 1:40 pm - Reply

    Thanks for the example, how can we use quartz and activemq together. I just want send message based on some crone time.

  8. Brian 12th January 2013 at 4:58 pm - Reply

    Combing Quartz with JMS is pretty straight forward. You'll want to use the MethodInvokingJobDetailFactoryBean, that's the jobDetail bean in this tutorial, to invoke the JMSTemplate described in my JMS ActiveMQ tutorial. You should be able to get this functionality up and running very quickly by combining the code samples from both tutorials.

  9. naresh bhanawat 21st February 2013 at 5:10 am - Reply

    Could you please provide a sample configuration for JDBCJobStore in spring? Thanks

  10. YangSheep 14th March 2013 at 3:42 am - Reply

    Thanks for the example and detailed comments.

  11. vijay shankar 15th July 2013 at 12:17 pm - Reply

    Can you please provide me a code snap for scheduler for cluster environment.

  12. Raju muddana 5th November 2013 at 9:14 am - Reply


    I have Configured Quartz scheduler in my app with spring 3.2.2 as you explained above,it is working fine.

    But While stopping server/app i am getting some Memory Leaks like…..

    SEVERE: The web application [/app] appears to have started a thread named [schedularbeanfactoryobj_Worker-1] but has failed to stop it. This is very likely to create a memory leak.
    I have googled and try with some solutions but could not fixed this.

    How To Fix This,I need Some Help.

    Thanks & regards

  13. Binh Thanh Nguyen 24th July 2015 at 10:36 am - Reply

    Thanks, nice explanation

Leave A Comment