Home  >  Quartz

Quartz 2 Scheduler Pass Parameters to Job with JobDataMap using @PersistJobDataAfterExecution and @DisallowConcurrentExecution Example

By Arvind Rai, May 22, 2015
In this page we will walk through Quartz 2 scheduler passing parameters to Job with JobDataMap using @PersistJobDataAfterExecution and @DisallowConcurrentExecution example. We can pass any number of parameters to the job scheduled by Quartz. To play this role, Quartz provides JobDataMap which is a map in which we can put values as key/value pair. JobDataMap is obtained from JobDetail. In job class implementing Job interface, we access JobDataMap using JobExecutionContext of execute() method. @PersistJobDataAfterExecution and @DisallowConcurrentExecution are annotated at job class. @PersistJobDataAfterExecution enables JobDataMap to update data while execution and allows to re-store it after execution. To avoid concurrent execution, we must annotate our job class with @DisallowConcurrentExecution. We will discuss here complete example step by step.

JobDataMap

org.quartz.JobDataMap is used to put and get values for a job instance. If the job is annotated with @PersistJobDataAfterExecution, then after job execution job states are re-persisted. JobDataMap is used to pass parameters to scheduled job. Using JobDetail instance we get the instance of JobDataMap and then add the values which needs to pass to scheduled job.
JobDataMap jobDataMap=  jobDetail.getJobDataMap()
jobDataMap.put(PrintNameJob.NAME, "RAM");  
Within a job, to access the JobDataMap values, we can do as follows.
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String name = dataMap.getString(NAME);  
Get the JobDetail instance by JobExecutionContext and get the instance of JobDataMap using JobDetail instance.

@PersistJobDataAfterExecution and @DisallowConcurrentExecution Annotations

@PersistJobDataAfterExecution annotation which is clear by its name, is used on Job implementing class to update JobDataMap while execution and can re-store it after execution. While doing such task, concurrent execution should be avoided. So we must also annotate our class with @DisallowConcurrentExecution annotation.

Create a Job

For the demo, we are creating a job in which we will access two parameters from JobDataMap passed while scheduling the job, one is the name and another is count. While execution, we will update count and persist it again in JobDataMap. In every execution of job, the new instance of job is created. To check it, I have taken a member variable with the value "new object" and within execution we have changed its value. What we see in output is that this will always be "new object", means every time, new instance of job is created.
PrintNameJob.java
package com.concretepage.job;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class PrintNameJob implements Job {
	public static final String NAME = "name";
	public static final String COUNT = "count";
	private String flag = "new object";
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		JobDataMap dataMap = context.getJobDetail().getJobDataMap();
		//fetch parameters from JobDataMap
		String name = dataMap.getString(NAME);
		int count = dataMap.getInt(COUNT);
		JobKey jobKey = context.getJobDetail().getKey();
		System.out.println(jobKey+": "+ name+"-"+count+": flag="+flag);
		count++;
		//add next counter to JobDataMap
		dataMap.put(COUNT, count);
		flag= "object changed";
	}
} 

Run Scheduler with passing parameters to Job

We will create two job details and trigger for the demo and will be added to scheduler for race condition. Both will access the same job for 3 rounds with 5 seconds time interval. We will pass two parameters, name and count with different values using JobDataMap.
PassParameterByJobDataMap.java
package com.concretepage;
import java.util.Calendar;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import com.concretepage.job.PrintNameJob;
public class PassParameterByJobDataMap {
	public static void main(String[] args) throws SchedulerException {
		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
		Scheduler scheduler = schedulerFactory.getScheduler();
		//create first JobDetail and Trigger
		JobDetail jobDetail = JobBuilder.newJob(PrintNameJob.class).withIdentity("ramjob", "ourgroup").build();
		SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("ramtrigger", "ourgroup")
			    .startAt(new Date(Calendar.getInstance().getTimeInMillis()+ 5000))
			    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5)
			    		.withRepeatCount(3)).build();
		//add passing parameters to JobDataMap for first JobDetail 
		jobDetail.getJobDataMap().put(PrintNameJob.NAME, "RAM");
		jobDetail.getJobDataMap().put(PrintNameJob.COUNT, 11);
		scheduler.scheduleJob(jobDetail, trigger);
		//create second JobDetail and Trigger		
		jobDetail = JobBuilder.newJob(PrintNameJob.class).withIdentity("rahimjob", "ourgroup").build();
		trigger = TriggerBuilder.newTrigger().withIdentity("rahimtrigger", "ourgroup")
			    .startAt(new Date(Calendar.getInstance().getTimeInMillis()+ 5000))
			    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5)
			            .withRepeatCount(3)).build();
		//add passing parameters to JobDataMap for second JobDetail 		
		jobDetail.getJobDataMap().put(PrintNameJob.NAME, "RAHIM");
		jobDetail.getJobDataMap().put(PrintNameJob.COUNT, 21);
		scheduler.scheduleJob(jobDetail, trigger);
		scheduler.start();
		try {
			//wait for 30 seconds to finish the job
			Thread.sleep(30000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//shutdown scheduler gracefully
		scheduler.shutdown(true);
	}
} 
Find the output. The flag value "new object" shows that every time new object of job class is created.
ourgroup.ramjob: RAM-11: flag=new object
ourgroup.rahimjob: RAHIM-21: flag=new object
ourgroup.ramjob: RAM-12: flag=new object
ourgroup.rahimjob: RAHIM-22: flag=new object
ourgroup.ramjob: RAM-13: flag=new object
ourgroup.rahimjob: RAHIM-23: flag=new object
ourgroup.ramjob: RAM-14: flag=new object
ourgroup.rahimjob: RAHIM-24: flag=new object 

Download Complete Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS






©2019 concretepage.com | Privacy Policy | Contact Us