Pass parameters to Quartz Job Scheduler

How to pass parameter to Quartz Scheduler Cron Trigger example in Java.


Integration of Quartz scheduler with Spring boot. Java Quartz scheduler cron expression example. Spring quartz scheduler postgresql database example.

Quartz Scheduler:  
  1. Quartz is a richly featured, open source Job scheduling library. 
  2. Quartz can be used to create simple or complex schedules for executing multiple jobs. 
  3. Using quartz library, job can be schedule which can be executed instantly or to be executed later point of time. 
  4. Quartz also accepts cron expression using which complex jobs can be scheduled like
    "Run job after every 5 minutes" or "Run job every week on monday at 3 PM" etc.
Spring boot:
  1. Spring boot is (Spring + Configuration) bundle which helps you to develop application faster.
  2. Spring boot take care of many configurations and helps developer focus on business. 
  3. It includes an embedded tomcat (or jetty) server.

Spring Boot and Quartz Scheduler in Action.


Download complete source code of Quartz Scheduler with Spring Boot example using below link,
https://github.com/javabypatel/spring-boot-quartz-demo 

Example uses,
  1. Spring Boot 1.5.7
  2. Quartz 2.2.3
  3. PostgreSQL 9.4.1208
  4. Angular2
Application provides Sample UI using which you can,
  1. Schedule Simple Quartz Job.
  2. Schedule Cron Quartz Job.
  3. Pause Quartz Job.
  4. Resume Quartz Job
  5. Edit Quartz Job. 
  6. Delete Quartz Job.
  7. Unschedule Quartz Job. 
  8. Stop Quartz Job.
  9. Check if Job is currently Running.
  10. Get the current state of Quartz Job.
  11. Get the list of all Scheduled Jobs.
  12. Job and Trigger Listeners for doing any operations before and after job starts, Listeners also hels in taking any action in case of job misfires due to application shutdown etc.

Quartz Scheduler Working.


Quartz work on concept of Jobs and Triggers. 
  1. Job is anything that need to be executed when event occurs. 
  2. Trigger is basically a event which contains time as when this event should occur.
JOB is binded by TRIGGER. when trigger event occurs it executes associated job.

There are 2 types of trigger,
  1. Simple Trigger
  2. Cron Trigger
Simple Trigger:  SimpleTrigger is used if you need to execute job exactly once at a specific moment in time, or at a specific moment in time followed by repeats at a specific interval.

For example, if you want the trigger to fire at exactly 11:23:54 AM on January 13, 2015, or if you want it to fire at that time, and then fire five more times, every ten seconds.


Cron Trigger:  CronTrigger is often more useful than SimpleTrigger, It is used for scheduling jobs having complex time like if you need to execute job that recurs based on calendar-like notions, rather than on the exactly specified intervals.

With CronTrigger, you can specify firing-schedules such as "every Friday at noon", or "every weekday and 9:30 am", or even "every 5 minutes between 9:00 am and 10:00 am on every Monday, Wednesday and Friday during January".


In Sample application we will demonstrate below features using Quartz library.
 
package com.javabypatel.demo.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.scheduling.quartz.QuartzJobBean;

public interface JobService {
 boolean scheduleOneTimeJob(String jobName, Class<? extends QuartzJobBean> jobClass, Date date);
 boolean scheduleCronJob(String jobName, Class<? extends QuartzJobBean> jobClass, Date date, String cronExpression);
 
 boolean updateOneTimeJob(String jobName, Date date);
 boolean updateCronJob(String jobName, Date date, String cronExpression);
 
 boolean unScheduleJob(String jobName);
 boolean deleteJob(String jobName);
 boolean pauseJob(String jobName);
 boolean resumeJob(String jobName);
 boolean startJobNow(String jobName);
 boolean isJobRunning(String jobName);
 List<Map<String, Object>> getAllJobs();
 boolean isJobWithNamePresent(String jobName);
 String getJobState(String jobName);
 boolean stopJob(String jobName);
}


Demo application also explains Quartz listeners, 

There are 2 types of listeners in quartz.
  1. Quartz Job Listeners.
  2. Quartz Trigger Listeners.
Listeners are callback methods that executes on events.

If you want to perform any task before job starts or when job completes or when trigger got misfired due to application shutdown, Quartz listeners will be helpful.


Download complete source code from here


Quartz Scheduler + Spring Boot + Angular2 Project Setup in Eclipse.


  1. Download the project from github.
  2. Import the project in Eclipse using "Import" > "Existing Maven Project".
  3. Once import is done properly and all dependencies are downloaded, project will look like below,


Running application in your Environment


After setting project in Eclipse,
  1. Install PostgreSQL database.(If you are planning to use other database then make respective changes in pom.xml for loading driver and in application.properties file for providing database path)

  2. Create database name "quartzdemoapp" (if you want to use any other name then give the same database name in application.properties file by replacing "quartzdemoapp" by that name)

  3. Open command prompt in admin mode.

  4. Go to "ui-app" folder and execute "npm install" command as shown below, (Make sure you have node and npm installed.)

  5. Go to "ui-app" folder and execute "npm run server" command as shown below,

    This step will start server and ui-app will be deployed.

  6. Open the browser and hit http://localhost:8080/ you will see the application UI as shown above which will be used to schedule both simple and cron quartz job.

  7. Start the Spring-boot application by clicking on "SpringBootQuartzAppApplication.java" > Right click, Run as, "Java Application"
    Note: Server will be hosted on localhost and port as 7080. (
    http://localhost:7080/)
Note:
Client application is listening on port 8080 and Server application is listening on port 7080.

If you don't want to run 2 application separately, then transpile the typescript files to javascript and put those files in your web application as shown below,

For converting typescript files to javascript files,
  1. Open command prompt, navigate to ui-app folder and run "npm run build".
  2. After above step you will see "target" folder created inside "ui-app" folder, copy those files to your web application and run the server application.

Configuration files.


There are 3 configuration files,
  1. application.properties
  2. data.sql
  3. quartz.properties

application.properties :
It contains configuration for server and database as shown below,
server.port=7080 //Server will be listening on port 7080
spring.application.name=Scheduledemo

####### SPRING JPA ############
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
####### SPRING JPA ############

####### POSTGRES ############
spring.datasource.driver-class-name=org.postgresql.Driver

#create the database by name "quartzdemoapp", here I am using postgresql running on port 5432.
#if you want other database, change the url.
spring.datasource.url=jdbc:postgresql://localhost:5432/quartzdemoapp 

#put your database username below
spring.datasource.username=postgres 

#put your database password below
spring.datasource.password=admin    


####### POSTGRES ############


data.sql :
Quartz require jobs and triggers to be stored in database. 

data.sql contains SQL scripts that creates tables required by quartz to manage scheduler.

quartz.properties :
org.quartz.scheduler.instanceName=springBootQuartzApp
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=5 //number of concurrent jobs that can be run.
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.misfireThreshold=60000 //if job is delayed by 1 minute, don't consider it as misfire.
org.quartz.jobStore.tablePrefix=qrtz_ //prefix used for all quartz related tables
org.quartz.jobStore.isClustered=false
org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownHook.cleanShutdown=TRUE


Pass parameters to Quartz Job.


If you want to pass any custom data/parameters to Quartz job that you can used at the the time of job execution, You can use JobDataMap class.

There are two types of data that you can set while job creation,
  1. Primitive data types, OR 
  2. User defined objects
Note: It would be good practice to store primitive data types in JobDataMap to avoid object serialization issues.

For storing instance variable,
Class MyClass{
 String temp;
}

MyClass obj = new MyClass();
obj.temp = "sample data";
 
Scheduler scheduler = schedulerFactoryBean.getScheduler();
scheduler.getContext().put("myobject", obj);

For storing primitive types,
You can modify createJob method as shown below for storing key-value pairs.
protected static JobDetail createJob(){
 JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();

 // set job data map
 if(jobDataMap!=null && jobDataMap.size()>0){
  JobDataMap jobDataMap = new JobDataMap();
  jobDataMap.put("myKey", "myValue");
  factoryBean.setJobDataMap(jobDataMap);
 }
 factoryBean.afterPropertiesSet();
 return factoryBean.getObject();
}

You can access the same data/parameters at the time of job execution as shown below,
For retrieving stored key-value pairs.
JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();
String myValue = dataMap.getString("myKey");
System.out.println("Value:" + myValue);

For retrieving stored object, It will try to deserialize the bytes Object.
SchedulerContext schedulerContext = null;
try {
 schedulerContext = jobExecutionContext.getScheduler().getContext();
} catch (SchedulerException e1) {
 e1.printStackTrace();
}
MyClass yourClassObject = (MyClass) schedulerContext.get("myobject");

 

You may also like to see


Compress a given string in-place and with constant extra space.

Check whether a given string is an interleaving of String 1 and String 2.

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord.

Serialize and Deserialize a Binary Tree

Advanced Multithreading Interview Questions In Java

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Post a Comment