Planificación de tareas en Java mediante Quartz

Planificación de tareas en Java mediante Quartz

Introducción

Normalmente los negocios requieren que en determinados momentos se ejecuten tareas de forma automática, por ejemplo: “todos los viernes a las 15:00 enviar informes a clientes”.

Crear un sistema robusto y completo que de soporte a la ejecución de esas tareas, además de no ser una tarea fácil, sería como reinventar la rueda pues ya disponemos de frameworks maduros de libre uso como el que vamos a presentar en este tutorial.

Quartz es un framework open source, con licencia Apache 2.0 para la planificación y gestión de tareas.

Es usado activamente en conocidos proyectos y organizaciones como JBoss, Cocoon, Apache Jakarta,… ver más

Características principales

  1. Válido para aplicaciones tanto J2EE como J2SE.
  2. Planificación flexible de tareas, por ejemplo: el primer lunes de Enero de cada año a las 17:45.
  3. Mantenimiento del estado de las tareas incluso en caso de fallos y reinicios de máquinas.
  4. Posibilidad de participar en transacciones JTA.
  5. Posibilidad de trabajar en modo Clúster.
  6. Proporciona un completo API, con muchas clases de utilidad y muchos tipos Listener (JobListener, TriggerListener y SchedulerListener).

Principales clases e interfaces

A continuación describimos los componentes que lo compomen: Job, JobDetail, Trigger, JobStore, Scheduler.

org.quartz.Job

Definir una tarea es tan sencillo como implementar la interface org.quartz.Job cuya definición se muestra a continuación:

Como podéis observar, simplemente debemos implementar un método y lanzar una excepción en caso de error para que Quarz reintente su ejecución o no, en función de la configuración que especifiquemos.

org.quartz.JobDetail

Es una clase que almacena propiedades de una determinada tarea.

Las tareas se clasifican en grupos de tareas y cada tarea tiene un nombre único dentro del grupo. JobDetail define estás y otras propiedades.

Gracias a esta clasificación podemos pausar, iniciar, detener, etc. tareas o grupos de tareas de manera independiente al resto.

org.quartz.Trigger

Es una clase abstracta que define los instantes en que la tarea debe ser ejecutada, por ejemplo todos los lunes a las 16:00 de la tarde.

Existen varias implementaciones de esta clase pero las más usadas son:

org.quartz.SimpleTrigger

Permite especificar ejecuciones de tareas teniendo en cuenta los siguientes parámetros: fecha, hora, nº de repeticiones e intervalo entre repeticiones.
Por ejemplo, ejecutar la tarea X 3 veces el día 13/12/1976 a las 13:30 con 40 minutos entre cada ejecución.

Para que se haga una idea, la firma de uno de sus constructores es:

org.quartz.CronTrigger

Es el más utilizado, pues permite especificar mediante expresiones más complejas los instantes en los que deben ejecutarse las tareas.
Por ejemplo, todos los días 14 que caigan en jueves cada 5 minutos desde las 14:00 hasta las 18:00.

Aunque existe mucha funcionalidad de utilidad que permiten hacernos la vida más fácil a la hora de crear el CronTrigger, yo suelo usar un constructor que acepta una cadena de texto representando una expresión de tipo Cron de Unix: segundos, minutos, horas, días del mes, meses, días de la semana, [año] (observe que todos son obligatorios a excepción de el año).

“0 0 23 * * ?” La tarea será ejecutada todos los días a las 23:00
“0 20 15 * * 1 2007″ La tarea será ejecutada todos los domingos del año 2007 a las 15:20

Para más información acerca de CronTrigger haga clic aquí.

org.quartz.JobStore

Interface para manejar el almacenamiento y recuperación de la información de planificación (tareas, triggers, etc).

Implementaciones de org.quartz.JobStore:
org.quartz.simpl.RAMJobStore Es la implementación de por defecto, almacena la información en memoria RAM por lo que cuando la aplicación finaliza no se guarda el estado.
org.quartz.impl.jdbcjobstore.JobStoreTX Implementación que almacena la información en una dase de datos a través de JDBC. Diseñado para entornos no transaccionales.
org.quartz.impl.jdbcjobstore.JobStoreCMP Implementación que almacena la información en una dase de datos a través de JDBC. Diseñado para entornos transaccionales.

La elección del JobStore se define a través de la propiedad org.quartz.jobStore.class de el archivo de propiedades de Quartz quartz.properties, por ejemplo.
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

org.quartz.Scheduler

Su funcionalidad es almacenar y planificar las tareas (Job) en base a los Triggers, recuperar tareas fallidas, realizar reintentos y gestionar el estado del sistema de planificación.

Ejemplo. Planificación de tareas en modo programático.

A continuación y a modo de ejemplo vamos a crear una aplicación que lance una tarea cada 5 segundos.
Aunque la tarea podría realizar cualquier operación compleja, en este caso simplemente mostrará un mensaje por pantalla.

com.autentia.tutoriales.quartz.StatusMonitorJob.java

Implementación de la tarea:

com.autentia.tutoriales.quartz.StatusMonitor.java

Aplicación de escritorio que realiza la planificación de la tarea:

Ejemplo. Planificación de tareas en modo declarativo.

Por defecto, en la configuración de Quartz puede especificar tareas externamente a la aplicación en un archivo de nombre quartz_jobs.xml

Este método le ofrece una gran flexibilidad, ya que podrá añadir o eliminar tareas sin realizar la gestión de planificación dentro de la aplicación… simplemente deberá copiar las clases en el CLASSPATH de la máquina virtual Java.

quartz_jobs.xml

Aplicación Web para gestionar nuestras tareas (modo declarativo)

En el siguiente enlace http://prdownloads.sourceforge.net/quartz/quartz-web-app.zip puede obtener una útil aplicación Web para gestionar las tareas a través de una completa aplicación Web. Su uso queda fuera del alcance de este tutorial….
Los datos de acceso de por defecto son quartz tanto para el nombre de usuario como para la contraseña.

Direcciones de interés (en inglés)

Conclusiones

Quartz es un FrameWork maduro y muy extendido, que nos proporciona ampliar la funcionalidad de nuestros proyectos que basan en tareas de una forma fácil y flexible.
Sin lugar a dudas, Quartz es una opción a tener en cuenta en estos casos… Para más información diríjase a la documentación del proyecto.

Carlos García Pérez. Creador de MobileTest, un complemento educativo para los profesores y sus alumnos.
cgpcosmad@gmail.com