JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Configure Quartz Scheduler Jobs using XML File

November 8, 2013 by Krishna Srinivasan Leave a Comment

In this tutorial I would explain how to configure quartz scheduler using properties file and xml file. Properties file will be used for configuring the JobStore details and XML configuration path. XML will store the list of Job details and cron triggers. In my previous post I have explained how to setup quartz scheduler pro-grammatically. However, in web application or any huge applications having multiple jobs to be configured, correct approach is to use the XML configuration file. Lets look at the below example and post your questions in the comments section.

Required JAR Files

Add the following JSR files to the classpath before start running the below example application.

  • quartz-2.2.1.jar
  • quartz-jobs-2.2.1.jar
  • slf4j-api-1.7.5.jar
  • jta-1.1.jar

1. Create A Job

FirstJob.java

[code lang=”java”]
package javabeat.net.quartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class FirstJob implements Job{

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("This is my first quartz job!!");
}

}
[/code]

2. Create Properties File

quartz.properties

[code]
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = javabeat/net/quartz/quartz-config.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
[/code]

3. Create XML File with Quartz Job and Cron Trigger

quartz-config.xml

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData
http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version="1.8">

<schedule>
<job>
<name>FirstJob</name>
<group>DummyGroup</group>
<description>This is FirstJob</description>
<job-class>javabeat.net.quartz.FirstJob</job-class>
</job>
<trigger>
<cron>
<name>dummyTrigger</name>
<job-name>FirstJob</job-name>
<job-group>GroupDummy</job-group>
<!– It will run every 2 seconds –>
<cron-expression>0/2 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
[/code]

4. Run the Quartz Application

QuartzXmlExample.java

[code lang=”java”]
package javabeat.net.quartz;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzXmlExample {
public static void main(String args[]) throws SchedulerException {
// Creating scheduler factory and scheduler
SchedulerFactory factory = new StdSchedulerFactory(
"javabeat/net/quartz/quartz.properties");
Scheduler scheduler = factory.getScheduler();
// Start scheduler
scheduler.start();
}
}
[/code]

If you run the above example, it would work perfectly and job is invoked for every 2 seconds. Hope this helps you to understand how to configure quartz scheduler using XML file.

5. Why JTA JAR file?

You may get the following exception if you are not adding the jta.jar file to the classpath when running the above application. You can get these jar file from here. It looks like quartz libraries are internally using this JSr file for managing the transactions.

[code]
Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
at java.lang.Class.privateGetPublicMethods(Class.java:2571)
at java.lang.Class.getMethods(Class.java:1429)
at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1261)
at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1122)
at java.beans.Introspector.getBeanInfo(Introspector.java:414)
at java.beans.Introspector.getBeanInfo(Introspector.java:161)
at org.quartz.impl.StdSchedulerFactory.setBeanProps(StdSchedulerFactory.java:1393)
at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:1057)
at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1519)
at javabeat.net.quartz.QuartzXmlExample.main(QuartzXmlExample.java:13)
Caused by: java.lang.ClassNotFoundException: javax.transaction.UserTransaction
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
… 12 more
[/code]

Filed Under: Java Tagged With: Quartz Scheduler

How to Write Quartz JobListener?

November 8, 2013 by Krishna Srinivasan Leave a Comment

In my previous posts I have explained about writing simple quartz scheduler and how to list jobs. This tutorial explains how to write a listener for the scheduler. In certain scenarios, we have to execute few lines of code or log messages before and after the batch process. The listeners are very useful for achieving those goals. In quartz, JobListener interface provides jobToBeExecuted and jobWasExecuted as the callback methods for before and after every job is executed. These methods takes the parameter of JobExecutionContext, with this you can access the current Job details and print them. For the complete setup of the quartz scheduler, please refer my previous tutorial. If you have any questions, please write it in the comments section.

1. Create a Job

FirstJob.java

[code lang=”java”]
package javabeat.net.quartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class FirstJob implements Job{

@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("This is my first quartz job!!");
}

}
[/code]

2. Create Quartz Job Listener

FirstJobListener.java

[code lang=”java”]
package javabeat.net.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

public class FirstJobListener implements JobListener{

@Override
public String getName() {
return "FirstJobListener";
}

@Override
public void jobToBeExecuted(JobExecutionContext context) {
System.out.println("jobToBeExecuted : " + context.getJobDetail().getKey().toString());

}
@Override
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException arg1) {
System.out.println("jobWasExecuted : " + context.getJobDetail().getKey().toString());

}
@Override
public void jobExecutionVetoed(JobExecutionContext context) {
System.out.println("jobExecutionVetoed : " + context.getJobDetail().getKey().toString());
}

}
[/code]

3. Add Quartz Job Listener to Scheduler

QuartzExample.java

[code lang=”java”]
package javabeat.net.quartz;

import java.util.Date;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.SimpleTriggerImpl;

public class QuartzExample {
public static void main(String args[]) throws SchedulerException{
//Creating scheduler factory and scheduler
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();

//Creating Job and link to our Job class
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName("First Job");
jobDetail.setJobClass(FirstJob.class);

//Creating schedule time with trigger
SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
simpleTrigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
simpleTrigger.setRepeatInterval(2000);
simpleTrigger.setName("FirstTrigger");

//Start scheduler
scheduler.start();
scheduler.scheduleJob(jobDetail,simpleTrigger);

//Adding the listener
scheduler.getListenerManager().addJobListener(new FirstJobListener());
}
}
[/code]

Filed Under: Java Tagged With: Quartz Scheduler

How to Get List of Jobs in Quartz Scheduler?

November 8, 2013 by Krishna Srinivasan Leave a Comment

In my previous article I have explained about how to write a simple quartz scheduler. In some cases, you would like to get the list of Jobs running on the scheduler. It is obvious that there will be multiple batch process configured in a large applications. If you could get the list of jobs and the next triggered time for each job, it is good for developers to use in their programming. With the extension of my previous example, this tutorial adds code snippet for listing the jobs running on scheduler. This also get the next trigger time for that particular job. Hope this helps. If you have any questions, please write it in the comments section.

getJobGroupNames() method in the scheduler instance returns the list of jobs. Also you can use the size method to get number of jobs.

ListJobs.java

[code lang=”java”]
package javabeat.net.quartz;

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

import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.SimpleTriggerImpl;

public class ListJobs {
public static void main(String args[]) throws SchedulerException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
// Creating Job and link to our Job class
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName("First Job");
jobDetail.setJobClass(FirstJob.class);

// Creating schedule time with trigger
SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
simpleTrigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
simpleTrigger.setRepeatInterval(2000);
simpleTrigger.setName("FirstTrigger");

// Start scheduler
scheduler.start();
scheduler.scheduleJob(jobDetail, simpleTrigger);

for (String groupName : scheduler.getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher
.jobGroupEquals(groupName))) {
String jobName = jobKey.getName();
String jobGroup = jobKey.getGroup();
List<Trigger> triggers = (List<Trigger>) scheduler
.getTriggersOfJob(jobKey);
Date nextFireTime = triggers.get(0).getNextFireTime();
System.out.println("[jobName] : " + jobName + " [groupName] : "
+ jobGroup + " – " + nextFireTime);
}

}
}
}

[/code]

Filed Under: Java Tagged With: Quartz Scheduler

Quartz Scheduler Tutorial

November 8, 2013 by Krishna Srinivasan Leave a Comment

Schedulers are important for running the batch process in your application. There are plenty of Java scheduler frameworks available in the market. Among them, Quartz Scheduler is the most popular and most widely used by Java projects. This tutorial provides very simple example to write Quartz scheduler. When you complete reading this tutorial, you will be able to write your won quartz scheduler. If you have any questions, please write it in the comments section.

1. SetUp Quartz Scheduler

Get the quartz JSR files from here. Also you would need slf4j-api-1.7.5.jar to run the quartz examples. Quartz is internally using this API for the logging purposes. Add these files to the classpath and imprt to the eclipse environment. I assume that you have already created a Java project in eclipse.

2. Create A Quartz Job

As a first step, implement org.quartz.Job interface and write your own Job. You must override the method execute which will be invoked for the batch process. The below code snippet is the simple example for writing a Job.

FirstJob.java

[code lang="java"]
package javabeat.net.quartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class FirstJob implements Job{

	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println("This is my first quartz job!!");
	}

}
[/code]

3. Register Quartz Scheduler

This is the final step where we initialize the Quartz scheduler. The following are the steps to initialize this scheduler.

  1. Create scheduler factory which is required for getting the scheduler instance.
  2. Get the scheduler instance from the factory.
  3. Create the JobDetailImpl instance and register our FirstJob to that object.
  4. Create and set the values for trigger. Trigger is very important for setting the details about the frequecny of batch process.
  5. Start the scheduler
  6. Schedule the Job by linking our Job and trigger.
  7. Your Quartz scheduler is ready and running.

QuartzExample.java

[code lang="java"]
package javabeat.net.quartz;

import java.util.Date;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.SimpleTriggerImpl;

public class QuartzExample {
	public static void main(String args[]) throws SchedulerException{
		//Creating scheduler factory and scheduler
		SchedulerFactory factory = new StdSchedulerFactory();
		Scheduler scheduler = factory.getScheduler();

		//Creating Job and link to our Job class
		JobDetailImpl jobDetail = new JobDetailImpl();
		jobDetail.setName("First Job");
		jobDetail.setJobClass(FirstJob.class);

		//Creating schedule time with trigger
		SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
		simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
		simpleTrigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
		simpleTrigger.setRepeatInterval(2000);
		simpleTrigger.setName("FirstTrigger");

		//Start scheduler
		scheduler.start();
		scheduler.scheduleJob(jobDetail,simpleTrigger);
	}
}
[/code]

Filed Under: Java Tagged With: Quartz Scheduler

Quartz Job Scheduler – Example Code

February 21, 2013 by Krishna Srinivasan Leave a Comment

In this section we are going to develop a simple Quartz Scheduler application with the help of Quartz framework. That will display Hello World Quartz Scheduler :date & time on the console window after specified time schedule.

Before using Scheduler you have to instantiate it. For doing this some users may keep an instance of a factory serialized in a JNDI store, and some other users may find it just to instantiate and use a factory instance. Firstly create the instance of SchedulerFactory by getting the reference of org.Quartz.impl.StdSchedulerFactory Class. Invoke the getScheduler() method by this instance to instantiate the Scheduler.

Quartz Scheduler Application

We have published list of articles on latest Quartz scheduler.

  • Quartz Scheduler Articles and Tutorials
  • Quartz Scheduler Tutorial
  • Configure Quartz Scheduler Jobs using XML File

execute(): Any software components you want to schedule then you must implement the Job interface and override it execute() method.

JobExecutionContext: The JobExecutionContext object that is passed to execute() method provides the job instance with information about its run-time environment a handle to the Scheduler that executed it, a handle to the Trigger that triggered the execution, the job’s JobDetail object, and a few other items.

SchedulerFactory: SchedulerFactory is a interface provides a mechanism for obtaining client-usable handles to Scheduler instances.

StdSchedulerFactory(): A Class StdSchedulerFactory is a class and it is implementation of SchedulerFactory interface. Here it just using for create an instance of SchedulerFactory instance.

Scheduler: Scheduler interface is the main interface (API) to this functionality. It provides some simple operations like scheduling jobs, unschedulingjobs, starting/stopping/pausing the scheduler.

getScheduler():SchedulerFactoy interface having the getScheduler() method that returns an instance of Scheduler.

start(): This method is used to starts the Scheduler’s threads that fire Triggers. At the first time when we create the Scheduler it is in stand-by mode, and will not fire triggers. The scheduler can also be send back into stand-by mode by invoking the standby() method.

JobDetail(String name, String group, Class jobclass): The JobDetail object is created at the time the Job is added to scheduler. It contains various property settings like job name, group name and job class name. It can be used to store state information for a given instance of job class.

SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, long repeatInterval): Trigger objects are used to firing the execution of jobs. When you want to schedule the job, instantiate the trigger and set the properties to provide the scheduling.

DEFAULT_GROUP: It is a constant, specified that Job and Trigger instances are belongs to which group.

REPEAT_INDEFINITELY: It is a constant used to indicate the ‘repeat count‘ of the trigger is indefinite.

scheduleJob(JobDetail jd, SimpleTrigger st): This method is used to add the JobDetail to the Scheduler, and associate the Trigger with it.

Here is the code of Job Class:

1. Create a Job using Quartz’s Job Interface

HelloJob.java

[code lang=”java”]
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;public class HelloJob implements Job {
public void execute(JobExecutionContext arg0) throws JobExecutionException{
System.out.println(Hello World Quartz Scheduler: + new Date());
}
}
[/code]

Here is the code of Scheduler Class:

2. Create a Schedule with Trigger

HelloSchedule.java

[code lang=”java”]
import java.util.Date;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

public class HelloSchedule {
public HelloSchedule()throws Exception{
SchedulerFactory sf=new StdSchedulerFactory();
Scheduler sched=sf.getScheduler();
sched.start();
JobDetail jd=new JobDetail("myjob",sched.DEFAULT_GROUP,HelloJob.class);
SimpleTrigger st=new SimpleTrigger("mytrigger",sched.DEFAULT_GROUP,new Date(),
null,SimpleTrigger.REPEAT_INDEFINITELY,60L*1000L);
sched.scheduleJob(jd, st);
}
public static void main(String args[]){
try{
new HelloSchedule();
}catch(Exception e){}
}
}
[/code]

Filed Under: Java Tagged With: Quartz Scheduler

Quartz Interview Questions

August 5, 2010 by Krishna Srinivasan Leave a Comment

What is Quartz?

Quartz is a job scheduling system that can be integrated with, or used along side virtually any other software system. The term “job scheduler” seems to conjure different ideas for different people. As you read this tutorial, you should be able to get a firm idea of what we mean when we use this term, but in short, a job scheduler is a system that is responsible for executing (or notifying) other software components when a pre-determined (scheduled) time arrives.

Quartz is quite flexible, and contains multiple usage paradigms that can be used separately or together, in order to achieve your desired behavior, and enable you to write your code in the manner that seems most ‘natural’ to your project.

Quartz is very light-weight, and requires very little setup/configuration – it can actually be used ‘out-of-the-box’ if your needs are relatively basic.

Quartz is fault-tolerant, and can persist (‘remember’) your scheduled jobs between system restarts.

Although Quartz is extremely useful for simply running certain system processes on given schedules, the full potential of Quartz can be realized when you learn how to use it to drive the flow of your application’s business processes.
What is Quartz – From a Software Component View?

Quartz is distributed as a small java library (.jar file) that contains all of the core Quartz functionality. The main interface (API) to this functionality is the Scheduler interface. It provides simple operations such as scheduling/unscheduling jobs, starting/stopping/pausing the scheduler.

If you wish to schedule your own software components for execution they must implement the simple Job interface, which contains the method execute(). If you wish to have components notified when a scheduled fire-time arrives, then the components should implement either the TriggerListener or JobListener interface.

The main Quartz ‘process’ can be started and ran within your own application, as a stand-alone application (with an RMI interface), or within a J2EE app. server to be used as a resource by your J2EE components.

Why not just use java.util.Timer?

Since JDK 1.3, Java has “built-in” timer capabilities, through the java.util.Timer and java.util.TimerTask classes – why would someone use Quartz rather than these standard features?

There are many reasons! Here are a few:

  1. Timers have no persistence mechanism.
  2. Timers have inflexible scheduling (only able to set start-time & repeat interval, nothing based on dates, time of day, etc.)
  3. Timers don’t utilize a thread-pool (one thread per timer)
  4. Timers have no real management schemes – you’d have to write your own mechanism for being able to remember, organize and retreive your tasks by name, etc.

…of course to some simple applications these features may not be important, in which case it may then be the right decision not to use Quartz.

How can I control the instantiation of Jobs?

See org.quartz.spi.JobFactory and the org.quartz.Scheduler.setJobFactory(..) method.

How do I keep a Job from being removed after it completes?

Set the property JobDetail.setDurability(true) – which instructs Quartz not to delete the Job when it becomes an “orphan” (when the Job not longer has a Trigger referencing it).

How do I keep a Job from firing concurrently?

Make the job class implement StatefulJob rather than Job. Read the JavaDOC for StatefulJob for more information.

How do I stop a Job that is currently executing?

See the org.quartz.InterruptableJob interface, and the Scheduler.interrupt(String, String) method.

How do I chain Job execution? Or, how do I create a workflow?

There currently is no “direct” or “free” way to chain triggers with Quartz. However there are several ways you can accomplish it without much effort. Below is an outline of a couple approaches:

One way is to use a listener (i.e. a TriggerListener, JobListener or SchedulerListener) that can notice the completion of a job/trigger and then immediately schedule a new trigger to fire. This approach can get a bit involved, since you’ll have to inform the listener which job follows which – and you may need to worry about persistence of this information.

Another way is to build a Job that contains within its JobDataMap the name of the next job to fire, and as the job completes (the last step in its execute() method) have the job schedule the next job. Several people are doing this and have had good luck. Most have made a base (abstract) class that is a Job that knows how to get the job name and group out of the JobDataMap using special keys (constants) and contains code to schedule the identified job. Then they simply make extensions of this class that included the additional work the job should do.

In the future, Quartz will provide a much cleaner way to do this, but until then, you’ll have to use one of the above approaches, or think of yet another that works better for you.

Why isn’t my trigger firing?

The most common reason for this is not having called Scheduler.start(), which tells the scheduler to start firing triggers.

The second most common reason is that the trigger or trigger group has been paused.

Daylight Saving Time and Triggers

CronTrigger and SimpleTrigger each handle daylight savings time in their own way – each in the way that is intuitive to the trigger type.

First, as a review of what daylight savings time is, please read this resource: http://webexhibits.org/daylightsaving/g.html . Some readers may be unaware that the rules are different for different nations/contents. For example, the 2005 daylight savings time starts in the United States on April 3, but in Egypt on April 29. It is also important to know that not only the dates are different for different locals, but the time of the shift is different as well. Many places shift at 2:00 am, but others shift time at 1:00 am, others at 3:00 am, and still others right at midnight.

SimpleTrigger allows you to schedule jobs to fire every N milliseconds. As such, it has to do nothing in particular with respect to daylight savings time in order to “stay on schedule” – it simply keeps firing every N milliseconds. Regardless your SimpleTrigger is firing every 10 seconds, or every 15 minutes, or every hour or every 24 hours it will continue to do so. However the implication of this which confuses some users is that if your SimpleTrigger is firing say every 12 hours, before daylight savings switches it may be firing at what appears to be 3:00 am and 3:00 pm, but after daylight savings 4:00 am and 4:00 pm. This is not a bug – the trigger has kept firing exacly every N milliseconds, it just that the “name” of that time that humans impose on that moment has changed.

CronTrigger allows you to schedule jobs to fire at certain moments with respect to a “gregorian calendar”. Hence, if you create a trigger to fire every day at 10:00 am, before and after daylight savings time switches it will continue to do so. However, depending on whether it was the Spring or Autumn daylight savings event, for that particular Sunday, the actual time interval between the firing of the trigger on Sundary morning at 10:00 am since its firing on Saturday morning at 10:00 am will not be 24 hours, but will instead be 23 or 25 hours respectively.

There is one additional point users must understand about CronTrigger with respect to daylight savings. This is that you should take careful thought about creating schedules that fire between midnight and 3:00 am (the critical window of time depends on your trigger’s locale, as explained above). The reason is that depending on your trigger’s schedule, and the particular daylight event, the trigger may be skipped or may appear to not fire for an hour or two. As examples, say you are in the United States, where daylight savings events occur at 2:00 am. If you have a CronTrrigger that fires every day at 2:15 am, then on the day of the beginning of daylight savings time the trigger will be skipped, since, 2:15 am never occurs that day. If you have a CronTrigger that fires every 15 minutes of every hour of every day, then on the day daylight savings time ends you will have an hour of time for which no triggerings occur, because when 2:00 am arrives, it will become 1:00 am again, however all of the firings during the one o’clock hour have already occurred, and the trigger’s next fire time was set to 2:00 am – hence for the next hour no triggerings will occur.

How do I improve the performance of JDBC-JobStore?

There are a few known ways to speed up JDBC-JobStore, only one of which is very practical.

First, the obvious, but not-so-practical:
* Buy a better (faster) network between the machine that runs Quartz, and the machine that runs your RDBMS.

* Buy a better (more powerful) machine to run your database on.

* Buy a better RDBMS.

Now for something simple, but effective: Build indexes on the Quartz tables.

Most database systems will automatically put indexes on the primary-key fields, many will also automatically do it for the foreign-key field. Make sure yours does this, or make the indexes on all key fields of every table manually.

Next, manually add some additional indexes: most important to index are the TRIGGER table’s “next_fire_time” and “state” fields. Last (but not as important), add indexes to every column on the FIRED_TRIGGERS table.

Create Table Indexes

[code]create index idx_qrtz_t_next_fire_time on qrtz_triggers(NEXT_FIRE_TIME);
create index idx_qrtz_t_state on qrtz_triggers(TRIGGER_STATE);
create index idx_qrtz_t_nf_st on qrtz_triggers(TRIGGER_STATE,NEXT_FIRE_TIME);
create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
create index idx_qrtz_ft_trig_group on qrtz_fired_triggers(TRIGGER_GROUP);
create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
create index idx_qrtz_ft_trig_n_g on qrtz_fired_triggers(TRIGGER_NAME,TRIGGER_GROUP);
create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(INSTANCE_NAME);
create index idx_qrtz_ft_job_name on qrtz_fired_triggers(JOB_NAME);
create index idx_qrtz_ft_job_group on qrtz_fired_triggers(JOB_GROUP);[/code]

My DB Connections don’t recover properly if the database server is restarted.

If you’re having Quartz create the connection data source (by specifying the connection parameters in the quartz properties file) make sure you have a connection validation query specified, such as:
Connection Validation Query

org.quartz.dataSource.myDS.validationQuery=select 0 from dual

This particular query is extremly efficient for Oracle. For other databases, you’ll need to think of an efficient query that always works as long as the connection is good.

If you’re datasource is managed by your application server, make sure the datasource is configured in such a way that it can detect failed connections.

I’m using JobStoreCMT and I’m seeing deadlocks, what can I do?

JobStoreCMT is in heavy use, under heavy load by many people. It is believed to be free of bugs that can cause deadlock. However, every now and then we get complaints about deadlocks. In all cases thus far, the problem has turned out to be “user error”, thus the list below is some things for you to check if you are experiencing deadlocks.
[code]
* Some databases falsely detect deadlocks when a tx takes a long time. Make sure you have put indexes on your tables (see improving performance of JDBCJobStore).
* Make sure you have at least number-of-threads-in-thread-pool + 2 connections in your datasources.
* Make sure you have both a managed and non-managed datasource configured for Quartz to use.
* Make sure that all work you do with the Scheduler interface is done from within a transaction. Accomplish this by using the Scheduler within a SessionBean that has its tx settings "Required" and "Container". Or within a MessageDrivenBean with similar settings. Finally, start a UserTransaction yourself, and commit the work when done.
* If your Jobs’ execute() methods use the Scheduler, make sure a transaction is in progress by using a UserTransaction or by setting the Quartz config propery "org.quartz.scheduler.wrapJobExecutionInUserTransaction=true".[/code]

Filed Under: Interview Questions Tagged With: Quartz Scheduler

Spring Job Scheduling support with JDK Timer and Quartz

July 31, 2010 by Krishna Srinivasan Leave a Comment

Not all applications are driven by user input. Some applications need to execute without any user intervention probably running at the background at specified intervals. For instance, a Virus Scanner application will be running in the background once in 2 days. Another instance could be where a Software could connect to its server repository once in a day for any updates. In this article we will see how Spring provides integration support for JDK Timer and Quartz that facilitates in writing job scheduling applications. The first half of the article draws an example for writing an application that uses JDK Timer with Spring support. The later section of the article discusses in writing an application that uses Quartz scheduling with some basic level of understanding done of cron expressions.

also read:

  • Spring Framework Article
  • Spring Framework Books (recommended)
  • Introduction to Spring Framework
  • Spring and Hibernate Integration

Integrating JDK Timer with Spring Framework

In this section, we will see how to integrate Spring with JDK Timer task objects. JDK Timer task objects provide support for execution of any task driven by a timer. Let us assume that we want to write a service that will periodically check for internet connection and logs the connection status. We will also imagine that this service has to run periodically all through the day with an interval of 30 minutes.

Writing the service

Following class provides the listing representing the internet connection service.

InternetConnectionCheckService.java

[java]package net.javabeat.articles.spring.core.scheduling.timer;

import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

public class InternetConnectionCheckService {

public void checkConnection(){

if (doCheck()){
System.out.println(new Date() + " Internet connection available");
}else{
System.out.println(new Date() + " Internet connection not available");
}
}

private boolean doCheck(){

URL urlObject = null;
URLConnection urlConnection = null;
try{
urlObject = new URL("http://www.google.com");
urlConnection = urlObject.openConnection();
urlConnection.getContent();
return true;
}catch (Exception exception){
return false;
}
}
}[/java]

The above code is fairly simple. To check whether internet connection is available or not it opens up a connection to a well-known domain for getting the content in the doCheck() method. When the connection is a failure, exception will be thrown which means that the connection is not available.

Wrapping service as a timer task

Now that we have written a service, we will see how to wrap the service as a task that can be driven from a timer. Refer the following code,

InternetConnectionCheckTimerTask.java

[java]package net.javabeat.articles.spring.core.scheduling.timer;

import java.util.TimerTask;

public class InternetConnectionCheckTimerTask extends TimerTask{

private InternetConnectionCheckService service;

public InternetConnectionCheckService getService() {
return service;
}

public void setService(InternetConnectionCheckService service) {
this.service = service;
}

@Override
public void run() {
service.checkConnection();
}

}[/java]

We have written a timer task class which extends the java.util.TimerTask class. The run() method is overridden for performing any operation. In this case, the operation will be calling the internet connection service to check for the connection status. Note that timer task is dependant on internet connection service object. Later on, we will see how to wire both these objects.

Configuration

So far we haven’t specified the repeating interval of 30 minutes at which the service has to be executed. In fact, Spring already provides the support through configuration. Have a look at the following configuration file representing the application’s context.

timer.xml

[java]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

<bean id="connectionCheckService">
</bean>

<bean id="connectionCheckTimerTask">
<property name="service" ref="connectionCheckService" />
</bean>

<bean id="scheduledConnectionCheckTimerTask">
<property name="delay" value="2000" />
<property name="period" value="30000" />
<property name="timerTask" ref="connectionCheckTimerTask" />
</bean>

<bean>
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledConnectionCheckTimerTask"/>
</list>
</property>
</bean>

</beans>
[/java]

We have declared the bean connectionCheckService representing the internet connection service. The second bean declaration defines the timer task with the bean id connectionCheckTimerTask. Because timer task is dependent on internet connection service, the dependency is injected through configuration.

Have a look at the following code snippet which declares the scheduled timer task object from Spring.

[java]
<bean id="scheduledConnectionCheckTimerTask">
<property name="delay" value="2000" />
<property name="period" value="30000" />
<property name="timerTask" ref="connectionCheckTimerTask" />
</bean>
[/java]

This class org.springframework.scheduling.timer.ScheduledTimerTask provides scheduling support for the execution of timer tasks. The property delay specified in milliseconds specifies the initial delay after which the task has to be executed. The value is mentioned as 2000 which means after the initial delay for the execution of the task will be 2 seconds. Next comes the property period which is also specified in milliseconds and that represents the interval after which the task will be repeatedly execution. In our case, the value given is 3000, so for every 30 minutes the task for execution will be fired. The final property is the timerTask which should point to the actual the timer task object, in this case it is going to be the connectionCheckTimerTask.

Triggering the scheduled tasks is done by TimerFactoryBean. It takes a list of scheduled timer task objects, in our case there is only one scheduled timer task object which is scheduledConnectionCheckTimerTask.

[java]
<bean>
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledConnectionCheckTimerTask"/>
</list>
</property>
</bean>
[/java]

Client

The client application in this example is going to do nothing other than just loading the application’s context. As soon the context is loaded service object, timer task object, scheduled timer task objects will be loaded and wired. Because we have also introduced the trigger bean which will trigger the scheduled timer task for execution, the internet connection will be running indefinitely with an interval of 30 minutes.

Client.java

[java]package net.javabeat.articles.spring.core.scheduling.timer;

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

public class Client {

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("timer.xml");
}
}[/java]

Spring Integration with Quartz

In this section, we will see how to integrate Spring with Quartz scheduling support. Quartz is extremely robust and powerful with advanced features such as distributed transactions and persistent jobs, the scope of which is completely outside of this article. We will write an example which will trigger an application for receiving work status for all the employees on all the business days (i.e from Monday till Friday) at 11 AM and 6PM.

Writing the service

Since the focus is more on explaining the advanced scheduling support, this service will do nothing other than printing on the console that the service has been invoked at appropriate hours.

StatusUpdateService.java

[java]package net.javabeat.articles.spring.core.scheduling.quartz;

import java.util.Date;

public class StatusUpdateService {

public void updateStatus(){
System.out.println(new Date() + " Update status Service invoked");
}
}[/java]

Wrapping service in a job bean

A Job Bean in Quartz encapsulates the task for execution and in our case, the task is as simple as calling the status update service. Have a look at the status update job bean.

StatusUpdateJobBean.java

[java]package net.javabeat.articles.spring.core.scheduling.quartz;

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

public class StatusUpdateJobBean extends QuartzJobBean{

private StatusUpdateService service;

@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
service.updateStatus();
}

public StatusUpdateService getService() {
return service;
}

public void setService(StatusUpdateService service) {
this.service = service;
}

}[/java]

Note that a job bean must extend QuartzJobBean and the method executeInternal() should be overridden for a job to execute. Note that later on in the configuration file we will see how the dependency between status update service and status update job bean is resolved.

Configuration

The configuration file provides the declaration of beans, wiring the dependency between beans as well the scheduling support for job execution. Have a look at the listing.

quartz.xml

[java]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

<bean id="statusUpdateService">
</bean>

<bean id="statusUpdateJob">
<property name="jobClass" value="net.javabeat.articles.spring.core.scheduling.quartz.StatusUpdateJobBean" />
</bean>

<bean id="statusUpdateTriggerBean">
<property name="jobDetail" ref="statusUpdateJob"/>
<property name="cronExpression" value="0 0 11,18 ? * MON-FRI *" />
</bean>

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

</beans>
[/java]

The first bean declaration with the id statusUpdateService declares an instance of StatusUpdateService service which has the core logic for the execution of a job. Next comes the declaration of JobDetailBean which is declared as follows,

[java]
<bean id="statusUpdateJob">
<property name="jobClass" value="net.javabeat.articles.spring.core.scheduling.quartz.StatusUpdateJobBean" />
</bean>
[/java]

The mandatory property for this job bean is jobClass. The property jobClass takes the fully qualified name of the JobBean which acts as wrapper in delegating the call to the real task of execution, in our case, the class name is net.javabeat.articles.spring.core.scheduling.quartz.StatusUpdateJobBean.

Next comes the declaration of the CronTriggerBean which will be acting as a scheduler providing the time period and interval on which the job has to be executed. This bean takes the mandatory properties jobDetail and cronExpression. The property jobDetail takes a reference to the job detail object that was just declared. The cronExpression property specifies the interval at which the job has to be executed. Here the value given is “0 0 11,18 ? * MON-FRI *”. This value has 7 parts with space as a delimiter the meaning of which is given as follows

  • First Field – Seconds
  • Second Field – Minutes
  • Third Field – Hours
  • Fourth Field – Day of the Month
  • Fifth Field – Month
  • Sixth Field – Day of week
  • Seventh Field – Year

Every value in the field can either take a single value (Eg: 1), comma-separated (Eg: 1,3,5) or range-based (Eg: 1-10). There are wild-card charactes ‘*’ and ‘?’ carrying special meaning. When ‘*’ is used against a field, it indicates all the values. For example, when ‘*’ is used for the third field, then it mean for all hours or for every hours. When ‘?’ is used it indicates that the field doesn’t carry any value.

So, coming back to our example, the value specified is “0 0 11,18 ? * MON-FRI *” which means “For every second in every minute, but during the hours 11 AM and 6 PM (not considering any day in a month), for all the months ranging from Monday till Friday in every Year” execute the given task.

also read:

  • Spring Framework Article
  • Spring Framework Books (recommended)
  • Introduction to Spring Framework
  • Spring and Hibernate Integration

Conclusion

We have seen how to write Job Scheduling applications with JDK Timer and Quartz objects with the help of Spring. It can be seen that for an application requiring basic scheduling support, it is wise to choose JDK Timer, however for applications that requires more sophisticated scheduling support; it is preferable to choose Quartz.

Filed Under: Spring Framework Tagged With: JDK Timer, Quartz Scheduler

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved