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 :
- Spring 3.1.2.RELEASE
- Quartz 1.8.6
- Eclipse 4.2
- Maven 3
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>
The Unix cron expression is highly flexible and powerful, read more in following websites :
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 ~
Jobs added with no trigger must be durable.. I am facing this issue.. can you pls help
Works for me , thanks!!
Where does the XML reside within the project ? I’m speaking of the XML shown in section 3.1, 4.1, 5,
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 ?
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
I have a similar requirement?? did u get any solution
Hi Mkyong
i am using the quartz schduler in our application where in the example we are specifying the applicationxml context from the Spring-Quartz.xml is it mandatory to have that xml for every scheduler or we can embed the same with existing xml will it work
Hi mkyong,
I want to test JobDetailBean as runMeJob, how to do it, please?
Great help in understanding basics.
Hi,
I am Setting requestRecovery(true) to recover the job that was running during server hard shut-down. But it is not working with quartz 1.8.6. I tried in different forms but failed. later I just tested with my old quartz jar 1.6.2 and it works. Below is my sample code.
JobDetail myJob = new JobDetail();
myJob.setName(“TestJob”);
myJob.setGroup(“JobGroup”);
myJob.setJobClass(Alarm.class);
myJob.setRequestsRecovery(true);
SimpleTrigger myTrigger = new SimpleTrigger();
myTrigger.setName(“TestTrigger”);
myTrigger.setGroup(“TriggerGroup”);
myTrigger.setStartTime(1234567890);
myTrigger.setRepeatCount(0);
myTrigger.setMisfireInstruction(MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_
COUNT);
mySched.scheduleJob(myJob, myTrigger);
Is this an bug in quartz 1.8.6 or do I miss anything special to configure which was actually not required in quartz 1.6.2. If so, can someone put a sample code to show how to achieve it.
Hi! If you schedule a job this way, it will have dependency injection as well?
Please update the post as SPR-8581 bug report has been resolved.
Thank you for this 🙂 this guide allowed me to create a simple scheduler as a study
Hi,
This line :
org.springframework.scheduling.quartz.QuartzJobBean;
has an error :
The import org.springframework.scheduling.quartz cannot be
resolved.
Can you please help me ?
Thanks
Hi mkyong,
I used Quartz scheduler in my Spring-Hibernate App based on You Nice Explanation.It is working fine,But The Threads Started for Quartz Scheduler are not destroying…and my server gives Errors(Memory Leaks) like….
org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
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 Tried With Many solutions to shutdown those threads but could not fixed.Can anybody Help To fix this.(i am using spring3.2.2 and quartz1.8.6)and also tried with quartz2.2.
Thanks
raju.
Hi Raju – Could you please guide how we can developed application with hibernate + spring + quartz? Could you please provide your sample code?
Hi, is it possible to make spring not to trigger the cronjob is the previous trigged job is still running?
Hi Diana,
The jobs are synchonous by default. So, even if you trigger the task that is already executing, it will not fire the second.
If you want fire the same task at same time, should use assync methods.
Hi,
From Spring Doc…
“By default, Quartz Jobs are stateless, resulting in the possibility of jobs interfering with each other. If
you specify two triggers for the same JobDetail, it might be possible that before the first job has
finished, the second one will start. If JobDetail classes implement the Stateful interface, this won’t
happen. The second job will not start before the first one has finished. To make jobs resulting from the
MethodInvokingJobDetailFactoryBean non-concurrent, set the concurrent flag to false.
“
I finally created a class to be a singleton. It’s an static property of the task (not the job), with an internal flag (private Boolean running = false;) with a method to change status (public void changeStatus() {running = !running;}), and a method to know its value (isRunning()).
So when the task is running, it checks if there is another thread running:
if (!mySingleton.isRunning()) {
mySingleton.changeStatus();
//whatever the task has to do here
mySingleton.changeStatus();
} else {
logger.warn(“Task won’t be executed, there is another instance of this job running.”);
}
Something like that, I don’t have my code here. But from everything I tried, it was the only thing that actually avoid running the same task twice at the same time. (Of course, I haven’t tried all the possibilities, but that solution worked for me).
Sir ,
I am using Spring 3.1.1 and quartz 1.8.5 like above example .but i am getting exception like below .anyone help me !
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘job’ defined in class path resource [META-INF/applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property ‘jobclass’ of bean class [org.springframework.scheduling.quartz.JobDetailBean]: Bean property ‘jobclass’ is not writable or has an invalid setter method. Did you mean ‘jobClass’?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1396)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at com.rcent.samples.SchedulerApp.main(SchedulerApp.java:11)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property ‘jobclass’ of bean class [org.springframework.scheduling.quartz.JobDetailBean]: Bean property ‘jobclass’ is not writable or has an invalid setter method. Did you mean ‘jobClass’?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1064)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:924)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
… 13 more
Hi..
Thanks..it works gud but i have spring application, I am importing the quarts-job.xml in application-servlet.xml. There are no error’s and during the server startup it shows” Starting Quartz Scheduler now” but the task is not fired Any idea what might be the issue.
Thanks,
Nishith
can you post your Quartz Configurations..
Did you solve this issue, I am having the same issue
Great contribution! Straight to the point. Thanks a lot
When I execute the App.java, I am not able to see any output on the console.
The Eclipse console only shows:
Sep 18, 2013 12:53:32 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1113708: startup date [Wed Sep 18 12:53:32 IST 2013]; root of context hierarchy
Sep 18, 2013 12:53:32 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-quartz.xml]
Sep 18, 2013 12:53:32 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1a33d48: defining beans [runMeTask,runMeJob,simpleTrigger]; root of factory hierarchy
Can someone help me to get this resolved?
I am using spring 3.1.2 and quartz 1.8.6
Thanking in advance!!
Thank you very much, these is better than what I used to schedule a job. In fact, it solved me a problem. Thank you very much!
Its ok
How can i do a Unit test for this scheduler to see if it print the message in the write time interval?
Very good article. its easy to understand
It is very simple and concise article to understand the basic concepts. Thanks
Could not autowire field: org.processor.repository.NotificationRepository org.processor.services.ProcessorService.notificationRepository; nested exception is 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-job.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
when i try to integrate this project in my maven project i am recieving above error?
please help
Hi,
In my application youre tutorial give me this error:
java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
The solution to resolve it was:
xml-apis
xml-apis
1.4.01
Thank’s for all your help! Everyday when I have a problem, you have the solution! 😉
It’s a fail, sorry! 😀
Add in pom.xml:
xml-apis
xml-apis
1.4.01
Ok balise is escaped…
so:
dependency
groupId org.quartz-scheduler /groupId
artifactId quartz /artifactId
version 1.8.6 /version
/dependency
Sorry for spam 🙂
Your example works only if you use
If you like to work this application with JobDetailsBean you should fixed it:
public class RunMeJob extends JobDetailBean { // it is empty.
}
and RunMeTask must implement Job interface
public class RunMeTask implements Job {
public void execute(JobExecutionContext jec) throws JobExecutionException {
System.out.println(“Quartz test job executed.”);
}
}
Thanks Mkyong, you always explain the concepts simple and easy so that novice person also can understand. your articles are very helpful to me. Thank you so much.
It seems that issue of https://jira.springsource.org/browse/SPR-8581 has labeled as won’t fix so you can update your article.
There is a small addition needed for the downloaded version to fully build and work out of the box: Simply add this dependency to the pom.xml
org.junit
com.springsource.junit
3.8.2
test
jar
That way it would compile and run out of the box.
The bug SPR-8581, looks resolved. Could you try updating? I failed 🙁
Simple, well explained and functional. I have lost the count of the times I ended up in your blog looking for answers.
Thanks!
I fully agree with Gullermo.
Thanks! and keep the posts comming 😉
A Co-worker and I just said “We always land on this dude’s blog!” Thank you Mkyong
Nice example. Helped a lot. Thanks.
Excellent post, thanks!!!!!
Thank you !!!
Hi mkyong,
Your articles have always been a great help for me.
Thank you so much!
Hi mkyong,
I’m always follows your articles, it’s awesome to learn new things. i have one problem and I’m using spring with Quartz and every
thing working fine but some previous cofigured
triggers also got executed because they are stored
in Quartz tables. Manually we can delete all
un configured triggers and execute the application
but that is not a good practice, right? so i want to
remove all the triggers through any spring+quartz property
or some other solution , i think there is spring+quartz
property for this problem.but If any property is available
to handle this problem and if you know plz forward me your
valuable solution .
Actually the scenario is ,
suppose when i have configured 3 triggers in spring configuration file like
when server started all the triggers stored in Quartz tables with
corresponding cron triggers and job details. But if i
remove any of the trigger in my configuration like in above for example i removed second Trigger , one thing i removed that trigger from coniguration file only but not
from Quartz tables. at that time DBtrigger (removed trigger)
also executed. How to avoid that problem. can anyone help to me.
it’s very useful to me. i googled lot of sites but i didn’t
get a solution. In spring + Quartz integration , is there
any property is there to handle this problem or we need to
do some thing for this problem.
Please tell me if you know the solution.
Thanks in advance.
Hi ,
I am also looking for same thing. Quartz property to delete jobdetails from quartz table. please send if there is any property .
Thank you
Hi mkyong,
I am facing a problem with Quartz+Spring implementation in my project. My production environment is clustered i.e two jboss instances. Therefore the time at which the job is scheduled say at 5PM, the same from each server instance gets triggered, therefore causing duplicate runs of the same job. How do I ensure that only one job instance runs in a clustered environment?
Thanks and regards,
KB.
Hi KB,
The simplest way:
You may use a flag in your database to indicate if a proccess has begun or not.
Other ways:
Use serializable objects, if possible, and try avoid static variables;
Multithread may be controlled by the package java.util.concurrent, but depends on your scenario and JDK version.
Does quartz comes with an administration GUI to dynamically update triggers and jobs?
mkyong, ur blog rocks !!! just wanted to know how to schedule Spring-batch jobs using springframework.scheduling.quartz.
<job id="batchJob1" job-repository="jobRepository" incrementer="incrementer" xmlns="http://www.springframework.org/schema/batch"> <step id="step1" > <tasklet transaction-manager="jdbcTransactionManager" start-limit="100"> <chunk reader="batchReader" processor="batchProcessor" writer="batchWriter" commit-interval="4"/> </tasklet> </step> </job>Excellent …………..
Very helpful indeed .
It is requested if you can guide how to run a spring Batch in the most simplest way … 🙂
Hi mkyong,
I have used the quartz similar as you explained having cron trigger and with scheduleFactoryBean. But I have observed there are lot of Scheduleworker opened when job is running.Can you give some idea on this why it is opened that many scheduleworkers and how to control the same.
Thanks,
Vikram
Thank you very much.
Do you means web container? You can integrate Spring with normal servlet web application or other frameworks ?
Good one Mkyong!! Its simple and effective.
I have a requirement, where the crontrigger parameters can be changed from GUI and based on the configured values, I should schedule the job. Can you give any pointers to this ? How to configure the trigger parameters dynamically without configuring in the XML ?
Hello mkyong
Thank you for the article. It was very helpful when I was learning the stuff.
I am using Quartz with Spring and MySQL. It has been working fine. But recently we upgraded MySQL from 5.1 to 5.5.20. We started having issues since the upgrade. I posted the details at http://stackoverflow.com/questions/12042782/saving-quartz-triggers-in-mysql.
I also posted the same question at Springframwork forum. So far there have been no responses for both postings. I’d greatly appreciate it if you can take a look and provide some feedback.
Thanks
hi …
can you please give us example with quartz-2.1+ and spring-3.1+
and how to create CronTriggerFactoryBean and Scheduler and run dynamically not by defining it in the spring-bean-definition.xlm file
Hi there,
Is this what you’re looking for?
<beans:bean id="noOpJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <beans:property name="jobClass" value="com.mycompany.batch.job.QuartzSchedulerJob" /> <beans:property name="group" value="mycompany-quartz-batch" /> <beans:property name="jobDataAsMap"> <beans:map> <beans:entry key="jobName" value="noOpJob" /> <beans:entry key="message" value="No Operation Job." /> </beans:map> </beans:property> </beans:bean> <beans:bean id="noOpCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <beans:property name="jobDetail" ref="noOpJobDetail" /> <beans:property name="name" value="noOpJob" /> <beans:property name="cronExpression" value="0/60 * * * * ?" /> </beans:bean>Hi Anon,
First Thanks for the reply.
Actually I am trying something like this —-
JobDetailFactoryBean j = new JobDetailFactoryBean();
j.setJobClass(FirstJobDetails.class);
CronTriggerFactoryBean c1 = new CronTriggerFactoryBean();
c1.setJobDetail((JobDetail) j.getObject());
c1.setCronExpression(“0/30 * * * * ?”);
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
Trigger[] triggers = new Trigger[]{(CronTrigger) c1.getObject()};
schedulerFactoryBean.setTriggers(triggers);
schedulerFactoryBean.start();
try { JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setJobClass(MyQuartzJobTest.class); jobDetailFactoryBean.setName("job_name"); jobDetailFactoryBean.setGroup("group_name"); jobDetailFactoryBean.afterPropertiesSet(); SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean(); simpleTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject()); simpleTriggerFactoryBean.setStartDelay(20000); simpleTriggerFactoryBean.setRepeatInterval(20000); simpleTriggerFactoryBean.setBeanName("trigger_name"); simpleTriggerFactoryBean.setGroup("group_name"); simpleTriggerFactoryBean.afterPropertiesSet(); JobFactory jobFactory = new SpringBeanJobFactory(); SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(jobFactory); schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true); schedulerFactoryBean.afterPropertiesSet(); schedulerFactoryBean.setTriggers(new Trigger[] { simpleTriggerFactoryBean.getObject() }); schedulerFactoryBean.getScheduler().scheduleJob(jobDetailFactoryBean.getObject(), simpleTriggerFactoryBean.getObject()); schedulerFactoryBean.start(); } catch (Exception e) { System.out.println(" ..... Scheduler can not be started ... : error : " + e); e.printStackTrace(); }Hi,
This is just to keep you informed, that I am able to launch schedulers successfully with Spring 3.1 and Quartz 2.1.6.
The only configuration you may need to change is use JobDetailFactoryBean instead of JobDetailBean and use SimpleTriggerFactoryBean instead of SimpleTriggerBean.
Packages for above classes are same.
Hi Mkyong,
Nice article ! I need to set repeatInterval dynamically from POJO to SimpleTriggerBean, Could you please help me out on this !
Regards,
Maulik
Hi MKYONG,
I need to set repeatInterval dynamically (from POJO) in SimpleTriggerBean, could you please help me out how to set repeatInterval dynamically.
Great, but I cannot make it work. When I launch the main method I get: Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘…Job’ defined in class path resource [spring-quartz.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: NULL
I copied the dpendencies from your pom.xml 🙁
nice job i will integrate quartz in application but more than threads has started , i will create a shulder to send mail to list users but each thread send propore mail and each destination recive more than one mail.
can you help me please
i will do cron job for my webapplication(spring3.0)
H,
Nice post.But I am facing some different problem.
I have been successfully using quartz in my application . Basically I have quartz bundled inside the webapp1 which is running inside the Jboss.
But we have got another webapp2 running in the jboss which needs to have quartz job as well
Now what I need to do is to have quartz scheduler running in the jboss as some kind of service and both the webapps should be able to register their jobs on the single quartz scheduler.
I was able to create the quartz-service running inside the jboss using Mbean exposed by quartz.USing this approach my sample job is also getting triggered correctly.But now how to access the spring context inside the job which is running outside the spring application and scheduler is also not initialized by Spring.
I hope I get some help from you
Not really get you, Try this – Expose your method as web service, so that Quartz can call it.
Hi Mkyong,
this was a very nice and helpful tutorial. Everything is working as expected.
But now I went one step further trying to do a JPA call from within my Task class.
I injected a Dao object into my Task bean which is doing some database operations.
For the first call after intialization everything works fine. The Task bean is called and the database operations are executed. However after the first call if the Task bean is called for the secon time I get exceptions
java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.getActivePersistenceContext(EntityManagerImpl.java:1576)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.begin(EntityTransactionImpl.java:49)
at de.baien.scheduler.service.RunMeTask1.printMe(RunMeTask1.java:15)
at de.baien.scheduler.job.RunMeJob.executeInternal(RunMeJob.java:26)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
14.07.2012 18:06:18 org.quartz.core.ErrorLogger schedulerError
It seems that for the second call the dao bean is not instantiated.
Do you know why?
Thanks & Regards
Oliver
What’s your last error caused by? The JPA and beans should be instantiated during project start up, and end when the project is stop, or you instantiate it wrongly?
Thanks mkyong, I have one question:
What if I want to define several triggers? Each one execute different job.
How the bean configuration file would be?
I just have to repeat code several time?
This is really great article. Thanks!
I have one query. If I want to save the cronExpression value dynamically from UI into XML.
Is it possible with above Spring-Quartz combinition? If yes, can you please share the idea?
Thanks in advance!!
some change in above code as I cant edit the above comment.
public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jdMap = context.getMergedJobDataMap(); setRunMetask((RunMeTask) jdMap.get("runMeTask")); runMeTask.printMe(); }by using the above code..the program will run with out overlapping..and it will trigger the task only if the previous one was completed.
superb..very good example..but there is one flaw with the above one.
here the scheduler is triggering the task before the completion of previous task which makes it overlapping the tasks…to avoid it I have developed this code and tested which will be more helpful if you like it.
modified these classes:
public class RunMeJob implements StatefulJob
{
private RunMeTask runMeTask;
public void setRunMeTask(RunMeTask runMeTask) {
this.runMeTask = runMeTask;
}
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jdMap = context.getMergedJobDataMap();
setEmailRetriever((EmailRetriever) jdMap.get(“emailRetriever”));
runMeTask.printMe();
}
}
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.
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?
thanks mykong, you rock! 😉
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
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.
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!
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.
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 solution, but I’ve not seen it yet.
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
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
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.
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?
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?
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?
I have the same problem. If you find a solution, e-mail me…
Did you find solution. There is no repeatInterval property.
Thanks.
hi,
i try in my eclipse buy its thrown a error,
Please help….
add slf4j to your classpath
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 of 15 mins.
And I have another function:
boolean isInboxEmpty();
I want to do this:
if(isInboxEmpty()==false) {
checkEvery15Mins();
}
I want only the checkEvery15Mins function to start only if my inbox is empty.
is this possible?
THANKS! 🙂
Don’t think it is possible in Quartz, alternatively, you can create 2 schedulers :
1. isInboxEmptyScheduler() run every seconds (not recommend), and insert a flag into db if inbox is empty, otherwise delete the flag;
2. checkEvery15MinsScheduler() run every 15min, take the flag from db to indicate whether continue the function.
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.
Spring 2.5.x n 3 annotation is not much big different, you can view some of the examples in https://mkyong.com/tutorials/spring-tutorials/ . Still preparing the Spring 3 examples.
I want the scheduler to run automatically with out starting from main method. How could I do that? Please explain
Integrate quartz with Spring, put spring loader in your web.xml, and it will start automatically when your web application is started.
Hi mykyong,
I too have the same query. If i need to call the scheduler without calling main, in my already implemented spring code. How do i go about it?
by integrate quartz with Spring, put loader in web.xml do you mean this?
contextConfigLocation
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
/WEB-INF/Spring-Quartz.xml
I have done this, but I dont see the scheduler working.
Please help.
Replied you via email. Just copied the answer here 🙂
By default, Spring will look for “applicationContext.xml” in your classpth, so include it into the ” contextConfigLocation” is optional, unless you have a different file name , like “ABCDEFGapplicationContext.xml”.
In this case, you should link “Spring-Quartz.xml” into your “applicationContext.xml” , see this article – https://mkyong.com/spring/load-multiple-spring-bean-configuration-file/ , via “import resource” tag. And put “applicationContext.xml” in your class path, Spring will find it automatically. And of course, delete the settings in web.xml.
Great blog and thanks for the ideas. You gave me ambitionto write another blog post later on. I like your style.
+1, works out of the box in my webapp, thanks for the easy to follow tutorial!
Thanks…this was very useful!
Very good example. It worked well. Thanks so much.
Hi Mkyong, It is really good article, keep it up!!!.
I follow your article for my project. It works like a charm.
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!
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?
Do you means web container? You can integrate Spring with normal servlet web application or other frameworks via this generic method
https://mkyong.com/spring/spring-how-to-do-dependency-injection-in-your-session-listener/
or Struts framework
https://mkyong.com/struts/struts-spring-integration-example/