Quartz

De Dos Ideas.
Saltar a: navegación, buscar

Quartz es una libreria Java para programar la ejecución de tareas. Permite "agendar" trabajos a realizar, con una sintaxis similar a la del cron de Unix.

Quartz puede correr en prácticamente cualquier entorno Java, ya sea una Aplicacion Java SE o una Aplicacion Java EE.

Introducción a Quartz

Supongamos que tenemos una aplicación con un requerimiento mediante el cual necesita ejecutar cierta tarea cada una cantidad fija de tiempo.

Inicialmente podía pensarse en usar un java.util.Timer para solucionarlo... pero el requerimiento podía ser un podo más particular: que pasaría si se necesita ejecutar la tarea a una hora especifica? O todos los viernes a la noche? El java.util.Timer empieza entonces a mostrar sus limitaciones.

Quartz aparece entonces como una librería más que interesante y facil de usar para agendar tareas. A continuación un breve resumen de la libreria y su uso.

Qué es Quartz

Quartz es una libreria para poder agendar tareas y programar su ejecución en momentos específicos. De manera realmente muy simple, es posible programar una tarea para que se ejecute:

  • cada una cantidad de tiempo fija (ej: cada 1 hora)
  • repetidamente, en momentos determinados (ej: a las 10 de la noche de los martes y jueves)
  • en rangos de tiempo (del 10 al 15 de cada mes, a las 9 de la mañana)
  • en saltos de tiempo (los días impares del mes, a las 10 de la noche)
  • etc, etc, etc.

Quartz consiste muy básicamente de 3 componentes:

  1. La tarea a ejecutar (que implementa la interfaz Job)
  2. El scheduler (que administra y ejecuta las tareas)
  3. El trigger (el evento que activa en el scheduler la ejecución de la tarea)

Un ejemplo simple

Utilizar Quartz es realmente muy simple.

Creemos primero la tarea que queremos ejecutar:

public class Trabajo implements Job {
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Invasor Zim rulez!");
    }
}

Esta tarea simplemente impreme por standard output un mensaje. Obviamente, en una implementación real, podría contactar a un Business Object, un EJB o cualquier otra clase para que realice alguna actividad más compleja.

Luego, con la tarea ya creada, queda simplemente obtener el Scheduler e indicarle qué trigger dispara la ejecución de la tarea:

SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
sched = schedFact.getScheduler();
sched.start();
JobDetail jobDetail = new JobDetail("myJob", null, zim.quartz.job.Trabajo.class);
//el trigger se disparará cada 10 segundos
Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);
//Otro Ejemplo: ejecutar a las 11:26 de cada viernes (ver manual de uso)
//Trigger trigger = new CronTrigger("myTrigger", null, "0 26 11 ? * FRI");
trigger.setStartTime(new java.util.Date());
trigger.setName("myTrigger");
sched.scheduleJob(jobDetail, trigger);

Con esto la tarea queda agendada para ser ejecutada según lo configurado. Y la pregunta que obviamente surge de esto es: ¿dónde ubico este código en mi aplicación?

Realizar el schedule en una Aplicacion Java SE

En una Aplicacion Java SE, esta tarea es trivial. Se deberá agregar el código anterior al lugar apropiado de la aplicación (por ejemplo, en el main()).

Realizar el schedule en una Aplicacion Web

Una Aplicacion Web tiene una vuelta más: en general es útil ejecutar esto "cuando se deploya" la aplicación, y no por intervención del usuario.

Una manera de hacerlo es a través de un ServletContextListener. Otra opcion (menos elegante quizás) es crear un Servlet y sobreescribir el método init() del mismo. El método init() de cada servlet es ejecutado ni bien termina de deployarse la aplicación.

Otras opciones avanzadas

Una de las opciones más interesantes de Quartz es la posibilidad de funcionar en un Cluster, y asegurar que cada tarea se ejecute de manera única en todo el cluster. Así, se sincronizan las tareas para evitar ejecuciones duplicadas.

Más aún, si algún nodo falla, Quartz puede entonces decidir la ejecución de la tarea en otro nodo del cluster.

Ver también