Tomcat 7 e Quartz 2: come integrarli

Questo è un semplice esempio di come integrare le librerie di Quartz (alla versione 2.2.1) con Tomcat 7 utilizzando il listener predefinito di Quartz e i suoi file di configurazione.
Le dipendenze vengono gestite da Maven, e sono queste:

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>servlet-api</artifactId>
	<version>2.5</version>
	<scope>provided</scope>			
</dependency>
 
<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>		
<dependency>
	<groupId>javax.transaction</groupId>
	<artifactId>jta</artifactId>
	<version>1.1</version>
</dependency>

La configurazione base di quartz prevede:

  • Modifica al file web.xml
  • Creazione dei file di configurazione

Modifica al file web.xml

<context-param>
  <param-name>quartz:config-file</param-name>
  <param-value>/quartz.properties</param-value>
</context-param>
<context-param>
  <param-name>quartz:shutdown-on-unload</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>quartz:wait-on-shutdown</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>quartz:start-on-load</param-name>
  <param-value>true</param-value>
</context-param>  
 
<listener>
  <listener-class>
		org.quartz.ee.servlet.QuartzInitializerListener
	</listener-class>
</listener>

Creazione dei file di configurazione

Nel parametro quartz:config-file è indicato quale file contiene la configurazione di quartz. Per come è indicato in questo esempio, nella cartella resources creare il file quartz.properties con il seguente contenuto:

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================
 
org.quartz.scheduler.instanceName: QuartzScheduler
org.quartz.scheduler.instanceId: AUTO
 
org.quartz.scheduler.skipUpdateCheck: true
 
#============================================================================
# Configure ThreadPool  
#============================================================================
 
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 3
org.quartz.threadPool.threadPriority: 5
 
#============================================================================
# Configure JobStore  
#============================================================================
 
org.quartz.jobStore.misfireThreshold: 60000
 
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
 
#============================================================================
# Configure Plugins 
#============================================================================
 
org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin
 
org.quartz.plugin.jobInitializer.class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames: quartz-jobs.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound: true
org.quartz.plugin.jobInitializer.scanInterval: 120
org.quartz.plugin.jobInitializer.wrapInUserTransaction: false

Importante è la proprietà

	org.quartz.plugin.jobInitializer.fileNames: quartz-jobs.xml

che indica che quartz cercherà nel file quartz-jobs.xml l’elenco dei job e dei trigger da gestire. Creare questo file nella stessa directory del precedente. Questo è il contenuto di questo esempio:

Il file quartz-jobs.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_2_0.xsd"
    version="2.0">
 
    <pre-processing-commands>
        <delete-jobs-in-group>*</delete-jobs-in-group>  <!-- clear all jobs in scheduler -->
        <delete-triggers-in-group>*</delete-triggers-in-group> <!-- clear all triggers in scheduler -->
    </pre-processing-commands>
 
    <processing-directives>
        <!-- if there are any jobs/trigger in scheduler of same name (as in this file), overwrite them -->
        <overwrite-existing-data>true</overwrite-existing-data>
        <!-- if there are any jobs/trigger in scheduler of same name (as in this file), and over-write is false, ignore them rather then generating an error -->
        <ignore-duplicates>false</ignore-duplicates> 
    </processing-directives>
 
    <schedule>
 
	    <job>
	        <name>Empty</name>
	        <description>Esempio di job vuoto</description>
	        <job-class>it.nicola.esempi.cron.EmptyJob</job-class>
	    </job>
 
	    <trigger>
	        <cron>
	            <name>TriggerEmpty</name>
	            <job-name>Empty</job-name>
	            <cron-expression>0 0/1 * * * ?</cron-expression>
	        </cron>
	    </trigger>
    </schedule>
 
</job-scheduling-data>

In questo caso è presente un solo job, la cui implementazione è nella classe it.nicola.esempi.cron.EmptyJob, ed un trigger che esegue il job ogni minuto.

Implementazione del Job

Per implementare un Job basta “implementare” l’interfaccia org.quartz.Job ed il suo metodo execute. In questo esempio:

public class EmptyJob implements Job {
 
    public void execute(JobExecutionContext context)
     throws JobExecutionException {
 
    	System.out.println("Sono un Job e sono partito.");
 
    }
 
}

La struttura finale del progetto dovrebbe essere questa:

Tomcat 7 e Quartz 2: come integrarli. Struttura del progetto
Tomcat 7 e Quartz 2: come integrarli. Struttura del progetto

L’esempio

E’ possibile scaricare un questo esempio:

Per compilare:

mvn clean compile

Per creare il war:

mvn package

Per lanciare l’esempio:

mvn tomcat7:run

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>