Quartz HelloWorld Example
In this example we shall talk about the Quartz Scheduler, a Java library for job scheduling, with various features, which is also open source. It is licensed under the Apache 2.0 license. The Quartz Scheduler can create simple or complex schedules for executing jobs in an application and also includes features like support for JTA transactions and clustering.
A Quartz Scheduler is commonly used for system maintenance needs, to drive the workflow of a procedure, or even to work as a reminder for other services in an application.
The basic interfaces of the quartz API are the ones below:
Scheduler
: the basic component to schedule jobs.Job
: an interface represending the job to be scheduled. It is implemented by custom components that theScheduler
will execute.JobDetail
: used to define instances ofJobs
.Trigger
: a component that defines the schedule upon which a givenJob
will be executed.JobBuilder
: used to buildJobDetail
instances, which define instances of Jobs.TriggerBuilder
: used to buildTrigger
instances.
Here, we will use two Trigger
API classes of the library to create and schedule two different custom jobs
. The first trigger
is the SimpleTrigger
class of the library and the second is the CronTrigger
class.
Our preferred development environment is Eclipse. We are using Eclipse Juno (4.2) version, along with Maven Integration plugin version 3.1.0. You can download Eclipse from here and Maven Plugin for Eclipse from here. The installation of Maven plugin for Eclipse is out of the scope of this tutorial and will not be discussed. We are also using JDK 7_u_21.
Let’s begin,
1. Create a new Maven project
Go to File -> Project ->Maven -> Maven Project.
In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.
In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.snippets.enterprise"
and the “Artifact Id” variable to "quartzexample"
. The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.quartzexample"
and the project name as "quartzexample"
. Hit “Finish” to exit the wizard and to create your project.
The Maven project structure is shown below:
- It consists of the following folders:
- /src/main/java folder, that contains source files for the dynamic content of the application,
- /src/test/java folder contains all source files for unit tests,
- /src/main/resources folder contains configurations files,
- /target folder contains the compiled and packaged deliverables,
- the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.
2. Add quartz dependency
Add the quartz
dependency in Maven’s pom.xml
file, by editing it at the “Pom.xml” page of the POM editor, as shown below:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.snippets.enterprise</groupId> <artifactId>quartzexample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> </dependencies> </project>
As you can see Maven manages library dependencies declaratively. A local repository is created (by default under {user_home}/.m2 folder) and all required libraries are downloaded and placed there from public repositories. Furthermore intra – library dependencies are automatically resolved and manipulated.
3. Create the job
As referenced above, in order to create a job we must implement the Job
interface. It overrides the execute(JobExecutionContext context)
method. When the Job
‘s trigger
fires, this method is invoked by one of the Scheduler
‘s worker threads. The JobExecutionContext
object that is passed to this method provides the job instance with a handle to the scheduler that executed it, a handle to the trigger that triggered the execution and the job’s JobDetail
object.
Below, there are two custom jobs, HelloJob.java
and ByeJob.java
, which will use the different trigger classes to be triggered:
HelloJob.java
will be triggered by the SimpleTrigger
.
HelloJob.java
package com.javacodegeeks.snippets.enterprise.quartzexample.job; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.javacodegeeks.snippets.enterprise.quartzexample.service.HelloService; public class HelloJob implements Job{ private HelloService hs = new HelloService(); public void execute(JobExecutionContext context) throws JobExecutionException { hs.sayHello(); } }
ByeJob.java
will be triggered by the CronTrigger
.
ByeJob.java
package com.javacodegeeks.snippets.enterprise.quartzexample.job; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.javacodegeeks.snippets.enterprise.quartzexample.service.ByeService; public class ByeJob implements Job{ private ByeService bs = new ByeService(); public void execute(JobExecutionContext context) throws JobExecutionException { bs.sayGoodbye(); } }
Below, there are two services, HelloService.java
and ByeService.java
that are called by the HelloJob.java
and ByeJob.java
respectivelly to type a message.
HelloService.java:
package com.javacodegeeks.snippets.enterprise.quartzexample.service; import java.util.Date; public class HelloService { public void sayHello() { System.out.println("Hello geeks! Time is " + new Date()); } }
ByeService.java
package com.javacodegeeks.snippets.enterprise.quartzexample.service; import java.util.Date; public class ByeService { public void sayGoodbye() { System.out.println("Bye geeks! Time is " + new Date()); } }
4. Create the Scheduler and the Trigger
MyApp.java
class creates two JobDetail
objects. They are actually used to create the job instances. They use the JobBuilder
to instantiate each job:
newJob(Class<? extends Job> jobClass)
method sets the java class representing the job they are building.withIdentity(String name)
method sets aJobKey
with the given name and default group to identify theJobDetail
.build()
method builds each job.
There are also two Trigger
classes. They both use the TriggerBuilder.newTrigger()
to create the trigger instances, and the withIdentity(String name, String group)
method to set a triggerKey
with the given name and a group to identify the Trigger
.
Trigger1
is a SimpleTrigger
, which is used to fire a Job
at a given moment in time, and optionally repeated at a specified interval. It is set in the withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(30))
method, which creates a SimpleScheduleBuilder
set to repeat for 30 seconds with a 1 second interval.
Trigger2
is a CronTrigger
, which is used to fire a Job
at given moments in time, defined with Unix ‘cron-like’ schedule definitions. It uses the withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
method, which creates a CronScheduleBuilder
set to repeat every 5 seconds.
The build()
method is used to build each Trigger
.
Finally, two schedulers are also created, using new StdSchedulerFactory().getScheduler()
. Each scheduler starts the threads that fire the Triggers
with the start()
method and adds the given JobDetail
and associates the given Trigger
with it, using scheduleJob(JobDetail jobDetail, Trigger trigger)
.
MyApp.java
package com.javacodegeeks.snippets.enterprise.quartzexample; import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import com.javacodegeeks.snippets.enterprise.quartzexample.job.ByeJob; import com.javacodegeeks.snippets.enterprise.quartzexample.job.HelloJob; public class MyApp { public static void main(String[] args) { try { JobDetail job1 = JobBuilder.newJob(HelloJob.class).withIdentity("helloJob", "group1").build(); Trigger trigger1 = TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "group1") .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(30)).build(); Scheduler scheduler1 = new StdSchedulerFactory().getScheduler(); scheduler1.start(); scheduler1.scheduleJob(job1, trigger1); JobDetail job2 = JobBuilder.newJob(ByeJob.class).withIdentity("byeJob", "group2").build(); Trigger trigger2 = TriggerBuilder.newTrigger().withIdentity("cronTrigger", "group2") .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build(); Scheduler scheduler2 = new StdSchedulerFactory().getScheduler(); scheduler2.start(); scheduler2.scheduleJob(job2, trigger2); } catch(Exception e){ e.printStackTrace(); } } }
5. Run the application
If you run MyApp.java
class, the result will be something like the output below:
As you can see, the HelloJob.java
is executed every second for 30 seconds, whereas the ByeJob.java
is executed every 5 seconds forever.
Output
Hello Geeks !! Time is Tue Jan 20 23:39:41 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:41 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:41 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:42 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:43 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:44 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:39:45 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:45 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:46 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:47 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:48 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:49 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:39:50 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:50 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:51 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:52 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:53 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:55 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:39:55 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:55 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:56 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:57 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:58 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:39:59 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:00 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:00 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:01 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:02 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:03 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:04 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:05 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:05 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:06 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:07 EET 2015 Hello Geeks !! Time is Tue Jan 20 23:40:08 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:10 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:15 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:20 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:25 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:30 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:35 EET 2015 Bye Geeks !! Time is Tue Jan 20 23:40:40 EET 2015
6. Download the Eclipse Project
This was an example of how to schedule jobs with the quartz scheduler library.
You can download the full source code of this example here: QuartzHelloWorldExample.zip
hai,
can we write test cases for this code?
If Yes, can you explain how to write test cases?
Verry well presented. Thanks alot