Spring 3 + Quartz 1.8.6 scheduler example

Updated on 25 July 2012 – Upgrade article to use Spring 3 and Quartz 1.8.6 (it was Spring 2.5.6 and Quartz 1.6)

In this tutorial, we will show you how to integrate Spring with Quartz scheduler framework. Spring comes with many handy classes to support Quartz, and decouple your class to Quartz APIs.

Tools Used :

  1. Spring 3.1.2.RELEASE
  2. Quartz 1.8.6
  3. Eclipse 4.2
  4. Maven 3
Why NOT Quartz 2?
Currently, Spring 3 is still NOT support Quartz 2 APIs, see this SPR-8581 bug report. Will update this article again once bug fixed is released.

1. Project Dependency

You need following dependencies to integrate Spring 3 and Quartz 1.8.6

File : pom.xml


...
<dependencies>

	<!-- Spring 3 dependencies -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>3.1.2.RELEASE</version>
	</dependency>

	<!-- QuartzJobBean in spring-context-support.jar -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>3.1.2.RELEASE</version>
	</dependency>

	<!-- Spring + Quartz need transaction -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>3.1.2.RELEASE</version>
	</dependency>

	<!-- Quartz framework -->
	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz</artifactId>
		<version>1.8.6</version>
	</dependency>

</dependencies>
...

2. Scheduler Task

Create a normal Java class, this is the class you want to schedule in Quartz.

File : RunMeTask.java


package com.mkyong.common;

public class RunMeTask {
	public void printMe() {
		System.out.println("Spring 3 + Quartz 1.8.6 ~");
	}
}

3. Declare Quartz Scheduler Job

With Spring, you can declare Quartz job in two ways :

3.1 MethodInvokingJobDetailFactoryBean
This is the simplest and straightforward method, suitable for simple scheduler.


<bean id="runMeJob" 
 	class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		
	<property name="targetObject" ref="runMeTask" />
	<property name="targetMethod" value="printMe" />
		
</bean>

3.2 JobDetailBean
The QuartzJobBean is more flexible and suitable for complex scheduler. You need to create a class extends the Spring’s QuartzJobBean, and define the method you want to schedule in executeInternal() method, and pass the scheduler task (RunMeTask) via setter method.

File : RunMeJob.java


package com.mkyong.common;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class RunMeJob extends QuartzJobBean {
	private RunMeTask runMeTask;

	public void setRunMeTask(RunMeTask runMeTask) {
		this.runMeTask = runMeTask;
	}

	protected void executeInternal(JobExecutionContext context)
		throws JobExecutionException {

		runMeTask.printMe();

	}
}

Configure the target class via jobClass and method to run via jobDataAsMap.


<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean">
	
	<property name="jobClass" value="com.mkyong.common.RunMeJob" />
		
	<property name="jobDataAsMap">
		<map>
			<entry key="runMeTask" value-ref="runMeTask" />
		</map>
	</property>
		
</bean>

4. Trigger

Configure Quartz trigger to define when will run your scheduler job. Two type of triggers are supported :

4.1 SimpleTrigger
It allows to set the start time, end time, repeat interval to run your job.


        <!-- Simple Trigger, run every 5 seconds -->
	<bean id="simpleTrigger" 
                class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		
		<property name="jobDetail" ref="runMeJob" />
		<property name="repeatInterval" value="5000" />
		<property name="startDelay" value="1000" />
		
	</bean>

4.2 CronTrigger
It allows Unix cron expression to specify the dates and times to run your job.


	<!-- Cron Trigger, run every 5 seconds -->
	<bean id="cronTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerBean">
	
		<property name="jobDetail" ref="runMeJob" />
		<property name="cronExpression" value="0/5 * * * * ?" />
	
	</bean>
Note
The Unix cron expression is highly flexible and powerful, read more in following websites :

  1. http://en.wikipedia.org/wiki/CRON_expression
  2. http://www.quartz-scheduler.org/docs/examples/Example3.html

5. Scheduler Factory

Create a Scheduler factory bean to integrate both job detail and trigger together.


   <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="jobDetails">
	   <list>
	      <ref bean="runMeJob" />
	   </list>
	</property>
		
	<property name="triggers">
	    <list>
		<ref bean="simpleTrigger" />
	    </list>
	</property>
   </bean>

6. Spring Bean Configuration File

Complete Spring’s bean configuration file.

File : Spring-Quartz.xml


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="runMeTask" class="com.mkyong.common.RunMeTask" />

	<!-- Spring Quartz -->
	<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean">

		<property name="jobClass" value="com.mkyong.common.RunMeJob" />

		<property name="jobDataAsMap">
		  <map>
			<entry key="runMeTask" value-ref="runMeTask" />
		  </map>
		</property>

	</bean>

	<!-- 
	<bean id="runMeJob" 
            class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
		<property name="targetObject" ref="runMeTask" /> 
		<property name="targetMethod" value="printMe" /> 
	</bean> 
	-->

	<!-- Simple Trigger, run every 5 seconds -->
	<bean id="simpleTrigger" 
                class="org.springframework.scheduling.quartz.SimpleTriggerBean">

		<property name="jobDetail" ref="runMeJob" />
		<property name="repeatInterval" value="5000" />
		<property name="startDelay" value="1000" />

	</bean>

	<!-- Cron Trigger, run every 5 seconds -->
	<bean id="cronTrigger" 
                class="org.springframework.scheduling.quartz.CronTriggerBean">

		<property name="jobDetail" ref="runMeJob" />
		<property name="cronExpression" value="0/5 * * * * ?" />

	</bean>

	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobDetails">
			<list>
				<ref bean="runMeJob" />
			</list>
		</property>

		<property name="triggers">
			<list>
				<ref bean="simpleTrigger" />
			</list>
		</property>
	</bean>

</beans>

7. Demo

Run it ~


package com.mkyong.common;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args ) throws Exception
    {
    	new ClassPathXmlApplicationContext("Spring-Quartz.xml");
    }
}

Output to console.


Jul 25, 2012 3:23:09 PM org.springframework.scheduling.quartz.SchedulerFactoryBean startScheduler
INFO: Starting Quartz Scheduler now
Spring 3 + Quartz 1.8.6 ~ //run every 5 seconds
Spring 3 + Quartz 1.8.6 ~

Download Source Code

Download it – Spring3-Quartz-Example.zip (25 KB)

References

  1. Using Quartz Scheduler with Spring
  2. Quartz Official Website
  3. Struts 2 + Spring 3 + Quartz 1.8 example
author image

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities. Read all published posts by

Comments

avatar
newest oldest most voted
Neha
Guest
Neha

How we can use Quartz with database if I want to query over database in every 10 min ? Could you please developed a code for that ?

Hari Krishna
Guest
Hari Krishna

hi how to dynamically change cron expression during runtime. Like the cron expression will be changed in database;so according to change the cron expression should change

jack
Guest
jack

I have a similar requirement?? did u get any solution

Riz
Guest
Riz

Nice material regarding spring and quartz, thank you for the posting.
I had gone through your example and found that it is working fine as a stand-alone application!
But without the web archive help this can not be deployed on container.
Or if I am wrong what is the way to deploy this on container so that the job will run as per scheduled?

Jason
Guest
Jason

Thanks a lot for posting this. This is a great tutorial and I have been pulling my hair out trying to learn Spring and Quartz!

trackback
Spring Tutorials | J2EE Web Development Tutorials

[…] Spring + Quartz scheduler example Article about how Spring schedule a job with Quartz framework. […]

thangaraj
Guest
thangaraj

Hi Mkyong, It is really good article, keep it up!!!.
I follow your article for my project. It works like a charm.

AjayK
Guest
AjayK

Very good example. It worked well. Thanks so much.

Vikram
Guest
Vikram

Thanks…this was very useful!

mark
Guest
mark

+1, works out of the box in my webapp, thanks for the easy to follow tutorial!

Global Help
Guest
Global Help

Great blog and thanks for the ideas. You gave me ambitionto write another blog post later on. I like your style.

Spring_user
Guest
Spring_user

I want the scheduler to run automatically with out starting from main method. How could I do that? Please explain

Sripad
Guest
Sripad

Hi mkyong,
I’m newbie to Spring tech. The Spring scheduler example worked for me.
It’d be great if you provided the Spring3.0 ‘annotation’ based example.
Once again applause for your blog/work.

Regards,
Sripad.

Aki
Guest
Aki

Hi. I understand completely your tutorial. It is very well explained. However, I have some questions regarding this approach. For example, I created a job and scheduled it to run every after 15 mins. I have done it since your tutorial did an excellent job in explaining. How would I do it if I want an external factor to trigger the start of that job? In a casual way it goes like this: I have a function: void checkEvery15Minutes(); Let’s say that all the configurations of this function is set using beans and all. It will execute with an interval… Read more »

trackback
Running Java Applications as a Linux Service « :: if you never try you never know ::

[…] Using Java Service Wrapper, the complecated steps above can be simplified. The case study is scehduller will print log every one second. To know about quartz using spring support please check this article […]

trackback
Running Java Applications as a Linux Service « :: if you never try you never know ::

[…] Using Java Service Wrapper, the compleceted steps above can be simplified. The case study is scehduler will print log every one second. To know about quartz using spring support please check this article […]

Amulraj
Guest
Amulraj

hi,

i try in my eclipse buy its thrown a error,

	... 19 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	... 25 more

Please help….

prashant mudgal
Guest
prashant mudgal

Hi,
Thanks for this consolidated tutorial. But my quartz xml file shows an error saying that no setter found for property repeatInterval in org.springframework.scheduling.quartz.SimpleTriggerBean ,I am using spring 3.1 jar , and when i decompiled simpletriggerbean, i saw that there was no property called repeatInterval, Is this error of spring version? or something else?

Flavio Troia
Guest
Flavio Troia

I have the same problem. If you find a solution, e-mail me…

Uuganbold
Guest
Uuganbold

Did you find solution. There is no repeatInterval property.

Thanks.

elite
Guest
elite

Hi Mkyong,

I am able to set the scheduler by using cronjobtriggerbean but not able to schedule multiple jobs using cronjobtriggerbean. Seems to be possible of triggering one job ony. Is my understanding correct?

jaya
Guest
jaya

HI,

I manage to run your code on JBOSS but when change the name of runJob and runTask to something else its giving me null value exception in executeInternal method.

I replace the above two values in applicationcontext.xml and in respective java classes as well.

am I missing some place more where i need to change them?

Stewart G
Guest
Stewart G

Can I ask which versions of quartz and spring you used for this tutorial? I have been trying with Spring 3.1 and Quartz 2.1 but I get errors and when looking in the 3.1 release notes it mentions that it should work with Quartz 2.1.

The error I get is as follows:

SEVERE: StandardWrapper.Throwable
org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.JobDetailBean] for bean with name ‘runMeJob’ defined in ServletContext resource [/WEB-INF/quartz-servlet.xml]: problem with class file or dependent class; nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.JobDetailBean has interface org.quartz.JobDetail as super class

Foo
Guest
Foo

Use JobDetail”Factory”Bean. Some of the old “…Bean” won’t work with Quartz 2.x, the “…FactoryBean” will work with all versions according to the Spring Javadoc.

srihari
Guest
srihari

while i am running quartz timer service i got this error.If any knows could u help to solve this problem

Exception in thread “main” org.springframework.beans.factory.BeanCreationExcepti
on: Error creating bean with name ‘jdb’ defined in class path resource [spconfig
.xml]: Instantiation of bean failed; nested exception is org.springframework.bea
ns.BeanInstantiationException: Could not instantiate bean class [org.springframe
work.scheduling.quartz.JobDetailBean]: Constructor threw exception; nested excep
tion is java.lang.NoClassDefFoundError: org/apache/commons/collections/SetUtils

navi
Guest
navi
i am new in Spring+quartz scheduler ,actually i have one urgent project in which me have to integrate scheduler with my database MYSQL.how could i do,help me?


Foo
Guest
Foo

I wonder if it’s possible somehow to use the JobDetailFactoryBean (because is exposes the JobExecutionContext) and do everything with less XML than today… Passing in services via jobDataAsMap is not really pretty compared to using the MethodInvokingJobDetailFactoryBean that allows for normal @Autowired annotations. If seen that one could pass arguments along with the targetMethod, but these appear fixed upon preparation time of the method invoker… There’s no way (except rewriting the whole MethodInvokingJobDetailFactoryBean as I’ve not seen a good way to inject just some behaviour…) to pass the JobExecutionContext into a scheduled bean used with MethodInvokingJobDetailFactoryBean yet… Maybe there’s a… Read more »

san
Guest
san

And… i’ve one question, after i run it with:

package com.mkyong.common;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args ) throws Exception
    {
    	new ClassPathXmlApplicationContext("Spring-Quartz.xml");
    }
}

how do i stop it?
Anyway, thanks. Very Good Post.

Roger
Guest
Roger

Great tutorial! I’ve been swimming around in manuals for the last few hrs, but this one example not only worked but it clarified all of the past day’s reading! thx!

Gunjan Shah
Guest
Gunjan Shah

Hi,

This method works fine but I want servletContext object in the quartz job. I can I do that ?

How can I retrieve servletContext reference in executeInternal() method ??

Thanx,
Gunjan.

mt
Guest
mt

Nice work, I have been using annotation and trying to update some old apps which still in 2.5. Anyway, if just need to trigger a method in a particular object, it will be cleaner to use the MethodInvokingJobDetailFactoryBean. Then there is no need to extends the quartz detail.

http://static.springsource.org/spring/docs/2.5.x/reference/scheduling.html

love you site, alot of useful information. thanks

jordi
Guest
jordi

thanks mykong, you rock! 😉

Priya
Guest
Priya

hi Mkyong,

the post was very useful. I want my scheduler to run in a specific time/two everyday.. Can i configure it in my bean file? If so how should i proceed with that?
If not how should i do it?

bella
Guest
bella

Your tuto is really interesting.

I use Spring batch to access a BD and update some attributs. I want to know how i can do if my function to put in RunMetask is the itemWriter use in Spring Batch.

This function begin with a parameter List but i don’t know how to recover the list from the ItemWriter.

Please help me if you understand what I say.