Quartz within Tomcat using XML job descriptions

Objective is to make a counter using Quartz. Step by step we’ll do the following

  1. Create a custom context listener to initialize a counter,
  2. Create quartz properties file and xml jobs file,
  3. Schedule a job that would keep incrementing the counter,
  4. Create a servlet to view that counter.

1. Create a custom context listener to initialize a counter:- If we need to listen to various events within the servlet container event listeners give us the flexibility to do that. We have Servlet context-level (application-level) events and Session-level events. For more, look at the documentation.

“After the application starts up and before it services the first request, the servlet container creates and registers an instance of each listener class that you have declared. For each event category, listeners are registered in the order in which they are declared. Then, as the application runs, event listeners for each category are invoked in the order of their registration. All listeners remain active until after the last request is serviced for the application.”

We declare all the listeners we need in the xml file. QuartzInitializerListener will create the scheduler (MyScheduler) from the quartz.properties and set scheduler factory instance into the servletContext.

1
2
3
4
5
6
7
8
9
10
11
12
<context-param>
  <param-name>initcounter</param-name>
  <param-value>100</param-value>
</context-param>
<listener>
  <listener-class>
	com.napp.listener.MyServletContextListener
  </listener-class>	
  <listener-class>
	org.quartz.ee.servlet.QuartzInitializerListener
  </listener-class>
</listener>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyServletContextListener implements ServletContextListener {
  public static int counter = 0;
  final static Logger logger = LoggerFactory.getLogger(MyServletContextListener.class);
 
  public void contextDestroyed(ServletContextEvent arg0) {
    // TODO Auto-generated method stub
  }
 
  public void contextInitialized(ServletContextEvent arg0) {
    String initCounter = arg0.getServletContext().getInitParameter("initcounter");
    if ( initCounter!= null) {
	counter = Integer.parseInt(initCounter);
	logger.info("Set counter-" + counter);
    } else {
	logger.info("Coulnt read init counter, default is 0");
    }
  }
}

2. Create quartz properties file and xml jobs file:- Quartz.properties that contains information that the Scheduler Factory uses to create a scheduler.

1
2
3
4
5
6
7
8
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 = jobs.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
#org.quartz.plugin.jobInitializer.scanInterval = 1
#org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<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>hello-world-job</name>
	<group>hello-world-group</group>
	<description>Print a welcome message</description>
        <job-class>com.napp.job.HelloWorldScheduledJob</job-class>
        <job-data-map>
          <entry>
	    <key>param1</key>
	    <value>value1</value>
          </entry>
        </job-data-map>
    </job>
    <trigger>	
	<cron>
	  <name>helloworld-trigger</name>
	  <job-name>hello-world-job</job-name>
	  <job-group>hello-world-group</job-group>
	  <!-- It will run every 5 seconds -->
	  <cron-expression>0/5 * * * * ?</cron-expression>
	</cron>	
    </trigger>
  </schedule>
</job-scheduling-data>

3. Schedule a job that would keep incrementing the counter:-

1
2
3
4
5
6
7
public class HelloWorldScheduledJob implements Job {
  final static Logger logger = LoggerFactory.getLogger(HelloWorldScheduledJob.class);
  public void execute(JobExecutionContext arg0) throws JobExecutionException {
    logger.info("Incremening counter.");
    MyServletContextListener.counter = MyServletContextListener.counter+1;
  }
}

4. Create a servlet to view that counter:-

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SimpleServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {
    rsp.setContentType("text/html");
    PrintWriter out = rsp.getWriter();
    out.println("<html>");
    out.println("<head><title> Simple Servlet </title></head>");
    out.println("<body>");
    out.println("<p>Counter - " + MyServletContextListener.counter + "</p>");
    out.println("</body></html>");
    out.close();
  }
}

You can download the sample-web-app from here.