icono_twiter icono Facebook
Carlos García Pérez

Técnico especialista en informática de empresa (CEU).

Ingeniero Técnico en Informática de Sistemas (UPM)

Creador de MobileTest, Haaala!, Girillo, toi18n.

Charla sobre desarrollo de aplicaciones en Android.

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2008-10-31

Tutorial visitado 43.332 veces Descargar en PDF
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

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Fecha publicación: 2013-04-30-11:32:15

Autor: JaEvita

Hola: Muy bueno el artículo!!!
Estoy comenzando a utilizar Quartz en un proyecto ya creado con anterioridad y me surge un problema:
Necesito pasarle a un Job un JobData de un tipo complejo (Ej: .usingJobData(PROPIEDAD1, batch), donde batch es de tipo Batch), pues como no puedo hacer un constructor con parámetros para la clase que implementa Job...
Si tienes alguna idea de cómo pudiera simular algo así, sería muy bienvenida. O alguna sugerencia de otro framework Java (puro) que permita planificación en el orden de los segundos. Muchas gracias de antemano. Saludos

Fecha publicación: 2011-08-04-17:21:19

Autor: RuLas

Que tal Carlos ... creo que no fué muy clara mi pregunta...:D Es verdad que no usas spring, mi pregunta realmente era Bajo éste mismo ejemplo, ¿Cómo agrego otra tarea totalmente distinta dentro del mismo archivo de condiguración quartz_jobs.xml? ó solamente se puede configurar para una sola tarea.

Saludos Charly!! de antemano muchas Gracias

Fecha publicación: 2011-08-04-17:12:18

Autor: RuLas

Que tal Carlos ... creo que no fué muy clara mi pregunta...:D Es verdad que no usas spring, mi pregunta realmente era Bajo éste mismo ejemplo, ¿Cómo agrego otra tarea totalmente distinta dentro del mismo archivo de condiguración quartz_jobs.xml? ó solamente se puede configurar para una sola tarea.

Saludos Charly!! de antemano muchas Gracias

Fecha publicación: 2011-08-04-08:13:14

Autor: carlosgp

RuLas, en este tutorial no uso Spring.

Quartz no necesita para nada de Spring para cumplir su función, otra cosa es que Spring tenga clases de utilidades o facilite su integración por madio de la IoD.

Fecha publicación: 2011-08-04-01:36:26

Autor: RuLas

QUe tal Carlos oye una pregunta, necesito programar más de una tarea en una Planificación de tareas en modo declarativo. pero sin utilizar spring, tienes alguna idea de como poder realizar esto..?

Fecha publicación: 2008-11-18-10:12:05

Autor:

[MARTOSFRE] Muy buen tutorial, excelente trabajo. Continuen asi dios los bendiga