Spring Batch + Quartz Scheduler example

In this tutorial, we will show you how to use the Quartz scheduler framework to schedule a Spring batch job to run every 10 seconds.

Tools and libraries used

  1. Maven 3
  2. Eclipse 4.2
  3. JDK 1.6
  4. Spring Core 3.2.2.RELEASE
  5. Spring Batch 2.2.0.RELEASE
  6. Quartz 1.8.6

The relationship looks like the following :

Spring Batch <--> Spring QuartzJobBean <--> Quartz Frameworks

The QuartzJobBean is acts like a bridge between Spring batch and Quartz frameworks.

1. Project Dependencies

Spring need spring-context-support to support Quartz scheduler.


<project ...


	<!-- Spring Core -->

	<!-- QuartzJobBean in spring-context-support.jar -->

	<!-- Quartz framework -->

	<!-- Spring Batch dependencies -->


2. Spring Batch Jobs

A batch job to read a csv file and print out the content via a custom writer. Few points to highlight :

1. Configure the JobRegistryBeanPostProcessor bean, it registers Job beans with JobRegistry, so that QuartzJobBean is able to get the Job bean via JobRegister (JobLocator).
2. The JobLauncherDetails is extended QuartzJobBean, acts as a bridge between Spring batch and Quartz.


<beans xmlns="http://www.springframework.org/schema/beans"

  <!-- spring batch context -->
  <bean id="jobRepository"
	<property name="transactionManager" ref="transactionManager" />

  <bean id="transactionManager"
	class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

  <bean id="jobLauncher"
	<property name="jobRepository" ref="jobRepository" />

	<property name="jobRegistry" ref="jobRegistry" />

  <bean id="jobRegistry"
	class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
  <!-- spring batch context -->

  <bean id="report" class="com.mkyong.model.Report" scope="prototype" />

  <bean id="customWriter" class="com.mkyong.writers.CustomWriter" />

  <batch:job id="reportJob">
	<batch:step id="step1">
		<batch:chunk reader="cvsFileItemReader" writer="customWriter"

  <bean id="cvsFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">

	<!-- Read a csv file -->
	<property name="resource" value="classpath:cvs/input/report.csv" />

	<property name="lineMapper">
	  <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
		<property name="lineTokenizer">
			<property name="names" value="id,impressions" />
		<property name="fieldSetMapper">
			<property name="prototypeBeanName" value="report" />


  <!-- run every 10 seconds -->
  <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="triggers">
	  <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail" ref="jobDetail" />
		<property name="cronExpression" value="*/10 * * * * ?" />

  <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass" value="com.mkyong.quartz.JobLauncherDetails" />
	<property name="group" value="quartz-batch" />
	<property name="jobDataAsMap">
		<entry key="jobName" value="reportJob" />
		<entry key="jobLocator" value-ref="jobRegistry" />
		<entry key="jobLauncher" value-ref="jobLauncher" />
		<entry key="param1" value="mkyong1" />
		<entry key="param2" value="mkyong2" />


3. QuartzJobBean Example

This class is copied from Spring batch sample Github repository, with minor change to run the completed job by passing a new Date() each time the job is running.


package com.mkyong.quartz;

import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import org.quartz.JobExecutionContext;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.configuration.JobLocator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class JobLauncherDetails extends QuartzJobBean {

  static final String JOB_NAME = "jobName";

  private JobLocator jobLocator;

  private JobLauncher jobLauncher;

  public void setJobLocator(JobLocator jobLocator) {
	this.jobLocator = jobLocator;

  public void setJobLauncher(JobLauncher jobLauncher) {
	this.jobLauncher = jobLauncher;

  protected void executeInternal(JobExecutionContext context) {

	Map<String, Object> jobDataMap = context.getMergedJobDataMap();

	String jobName = (String) jobDataMap.get(JOB_NAME);

	JobParameters jobParameters = getJobParametersFromJobMap(jobDataMap);
	try {
		jobLauncher.run(jobLocator.getJob(jobName), jobParameters);
	} catch (JobExecutionException e) {

  //get params from jobDataAsMap property, job-quartz.xml
  private JobParameters getJobParametersFromJobMap(Map<String, Object> jobDataMap) {

	JobParametersBuilder builder = new JobParametersBuilder();

	for (Entry<String, Object> entry : jobDataMap.entrySet()) {
		String key = entry.getKey();
		Object value = entry.getValue();
		if (value instanceof String && !key.equals(JOB_NAME)) {
			builder.addString(key, (String) value);
		} else if (value instanceof Float || value instanceof Double) {
			builder.addDouble(key, ((Number) value).doubleValue());
		} else if (value instanceof Integer || value instanceof Long) {
			builder.addLong(key, ((Number) value).longValue());
		} else if (value instanceof Date) {
			builder.addDate(key, (Date) value);
		} else {
			// JobDataMap contains values which are not job parameters
			// (ignoring)

	//need unique job parameter to rerun the completed job
	builder.addDate("run date", new Date());
	return builder.toJobParameters();



4. Run It

Loads the Spring application context, the Quartz scheduler will run the “reportJob” every 10 seconds.


package com.mkyong;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {

	String springConfig = "spring/batch/jobs/job-quartz.xml";

	ApplicationContext context = new ClassPathXmlApplicationContext(springConfig);


Download Source Code


  1. Quartz – Enterprise Job Scheduler
  2. Spring 3 + Quartz 1.8.6 Scheduler Example
  3. QuartzJobBean Example
  4. Wiki : Cron
  5. Spring Batch + Spring TaskScheduler Example
author image


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


newest oldest most voted
A Dev in need of help
A Dev in need of help

I follow most of your tutorials, as they are always useful and seem to be the best source for an answer. However, I could use some additional help. How would I take a simple java application like this and convert it into an Enterprise App (ear)?


Spring Batch Quartz Scheduler Example is giving error “java.lang.NoClassDefFoundError: org.slf4j.impl.StaticLoggerBinder

java.lang.NoClassDefFoundError: org.slf4j.impl.StaticLoggerBinder

Tae Hyun Ahn
Tae Hyun Ahn

Thanks for your kindness tutorials. They are very useful.

I have a question.. What if I’d like to run 2 jobs in this sample Spring Batch project?
Do I have to make another xml files such as “job-quartz2.xml”, to make another jobRepository??

I thought I have to add one more tag(for another job) in “jobDetail” bean, but this caused an error like,
“Invalid content was found starting with element ‘map’.”…

Gaurav Bansal
Gaurav Bansal

Thanks for this tutorial… It is really useful. I have a small question in this tutorial you are having a map repository for Spring Batch Job and JobRegistry works on reading all Map data. What if I am forced to have a Database Job Repository for Spring Batch. I was not able to find any class for JobRegistry which supports DB based repository. If you can give any leads on that front will be great. Thanks in advance


Thanks!!!! it’s possible to schedule the job dynamically? By reading the value in table (for example)


Very Good ! How we can write junit test cases for this project ?


Thanks for this post. I have a question about the cron expression.
Can i set different cron expressions for different environments?
SIT – Every day
UAT-End of month
Pre Prod-End of month
Prod-End of month

This will help in testing the job and its scheduler in SIT