Quartz 2 tutorial on JBoss EAP and WildFly

User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 
It's time to learn new Quartz 2 API using JBoss EAP or WildFly. This tutorial shows how to create a simple Web application which will be deployed on the application server, triggering a Quartz Job. In the second part of it, we will show how to add an advanced configuration which includes a JDBC Job Store.

Using Quartz 2 API with JBoss EAP or WildFly

In the earlier versions of JBoss AS, Quartz was bundled along with the application server, now we will set up by ourselves: however don't worry it will take just a minute. You have two options in order to use Quartz

Option 1: Bundle Quartz in your Web application

This is the simplest option and it does not require any installation step on the application server. All you need is including the Quartz dependency in your pom.xml as follows:

 <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
  </dependency>
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
  </dependency>

If you are not using Maven to build your project, then you can simply download and bundle the Quartz libraries ( http://quartz-scheduler.org/downloads ) into your WEB-INF/lib folder.

Option 2: Install Quartz as a module in your application server

Create the following module structure under JBOSS_HOME/modules:
+---org
      +----quartz
                +-----main
                        module.xml
                        quartz-2.2.3.jar
                        quartz-jobs-2.2.3.jar
                        c3p0-0.9.1.1.jar
And here's module.xml file:
<module xmlns="urn:jboss:module:1.1" name="org.quartz">
  <resources>
    <resource-root path="quartz-2.2.3.jar"/>
    <resource-root path="quartz-jobs-2.2.3.jar"/>
    <resource-root path="c3p0-0.9.1.1.jar"/>
  </resources>
  <dependencies>
          <module name="org.slf4j"/>
          <module name="org.apache.log4j"/>
          <module name="javax.api"/>
  </dependencies>
</module>
Finally, you need to include the dependency to quartz either in your MANIFEST.MF file or jboss-deployment-structure.xml as in the following example:
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="org.quartz" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Coding a Quartz Test Servlet application

Now that you have arranged for Quartz libraries we will create a simple Quartz Servlet in it:
package com.mastertheboss;

import java.io.IOException;
import java.util.Date;
  
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

import org.quartz.*;
import org.quartz.impl.*;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.DateBuilder.*;
@WebServlet("/TestQuartz")
public class TestQuartz extends HttpServlet {

private static final long serialVersionUID = 1L;
        
   
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
          
        try {
            // step 1
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();
        sched.start();
        
          
        Date runTime = evenMinuteDate(new Date());
        // Trigger the job to run on the next round minute
        Trigger trigger = newTrigger()
           .withIdentity("trigger1", "group1")
           .startAt(runTime)
           .build();
        // Define job instance
        JobDetail job1 = newJob(HelloJob.class)
           .withIdentity("job1", "group1")
           .build();
                              
        // Schedule the job with the trigger 
        sched.scheduleJob(job1, trigger); 

       // Set response content type
        response.setContentType("text/html");

       // Actual logic goes here.
        PrintWriter out = response.getWriter();
        out.println("<h1>Quartz Job Scheduled in a minute</h1>");
       }
        
        
         catch ( Exception de) {
            throw new IOException(de.getMessage());
        }
    }
  
}
And here's the simple HelloJob class:
package com.mastertheboss;

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

public class HelloJob implements Job {
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println("Hello World! - " + new java.util.Date());
	}
}
Surprised by the changes in the Quartz Api ? actually quartz contains a pretty load of new features which are enumerated here: http://quartz-scheduler.org/documentation/quartz-2.x/migration-guide
The most evident for you at the moment are Quartz static initializers. Quartz 2.0 API provides a new builder-based API based on a Domain Specific Language (DSL) for constructing job and trigger definitions. Usage of static imports makes your code nice and clean when using the new DSL.
Here's for example how you used to create a JobDetail in older quartz Api:
JobDetail job = new JobDetail("myJob", "myGroup");
job.setJobClass(MyJobClass.class);
job.getJobDataMap().put("someKey", "someValue");
and here's the Quartz 2.0 version:
JobDetail job = newJob(MyJobClass.class)
    .withIdentity("myJob", "myGroup")
    .usingJobData("someKey", "someValue")
    .build();

The application will be running at the following URL http://localhost:8080/quartz-demo/TestQuartz/

Source code available here: https://github.com/fmarchioni/mastertheboss/tree/master/quartz/quartz-demo-wildfly