Esse artigo faz parte da revista Java Magazine edição 41. Clique aqui para ler todos os artigos desta edição

Imagem

Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. 

Tarefas na Hora com Quartz

Use o framework Quartz para criar e agendar tarefas no Java

Como utilizar passo a passo, a utilizar o framework open source Quartz. Dos conceitos fundamentais a um exemplo completo.

 

Ao desenvolver aplicações corporativas, é comum encontrar requisitos exigindo que determinados processos sejam executados em intervalos regulares (ou em horários específicos), sem intervenção humana. Esse planejamento, denominado agendamento de tarefas ou job scheduling, pode ser alcançado através de comandos do sistema operacional ou utilizando-se aplicativos especializados.

O framework open source Quartz oferece um pacote completo de funcionalidades para esse fim, permitindo a criação e a manipulação de tarefas agendadas. Neste artigo explicaremos conceitos essenciais do agendamento de tarefas e detalhes sobre a utilização do Quartz, através de um exemplo completo.

 

Agendamento no Java SE

A partir da versão 1.3 o Java passou a oferecer uma opção para agendamento de tarefas, através das classes java.util.Timer e java.util.TimerTask. Essa solução é bastante simples possuindo uma série de limitações, sendo adequada apenas em algumas situações (veja detalhes no artigo “Agendamento de tarefas em Java”). Ao utilizar essa API certas restrições se tornam evidentes:

  • O mecanismo de agendamento é pouco flexível, baseando-se apenas na data inicial e no intervalo de repetição das tarefas;
  • Cada objeto Timer cria uma nova thread em segundo plano, o que não é desejável em aplicações Java EE;
  • Não há a possibilidade de persistir tarefas, permitindo continuar a execução da tarefa posteriormente (ex.: quando o sistema reiniciar).

 

O Quartz disponibiliza funcionalidades para criação e execução de tarefas em Java, e resolve as limitações impostas pela API Timer/TimerTask. Além disso, oferece bastante flexibilidade e múltiplas opções de uso.

 

O framework Quartz

O Quartz permite criar e executar tarefas de muitos tipos e traz implementações para tarefas comuns (como envio de e-mails, execução de EJBs, execução de comandos nativos etc.).

O framework baseia-se em três conceitos fundamentais: job (tarefa), trigger (“gatilho”) e scheduler (agendador). Um job representa uma tarefa que se deseja executar, e é normalmente descrito através da interface org.quartz.Job. Essa interface inclui apenas um método encapsulando a lógica da tarefa:

 

public void execute (JobExecutionContext context)

  throws JobExecutionException;

 

Um trigger define os momentos em que a tarefa deve ser executada e dispara sempre que chega o instante de execução. O Quartz disponibiliza diversos tipos de triggers, tratando desde as situações mais simples, com a classe org.quartz.SimpleTrigger; até situações complexas, incluindo intervalos de tempo e dias específicos, usando org.quartz.CronTrigger (veja mais no quadro “Entendendo a classe CronTrigger”).

O scheduler possui um registro de todos os triggers e tarefas programadas e coordenada a sua execução. Não existe nenhum vínculo direto entre tarefas e triggers: ambos podem ser manipulados separadamente. A separação entre  a tarefa e o seu agendamento é um dos pontos fortes do framework Quartz. Isso permite que uma mesma tarefa seja executada em situações completamente diferentes, e facilita o reaproveitamento da lógica das tarefas e dos triggers.

 

Primeiros passos

Para agendar uma tarefa usando o Quartz, o primeiro passo consiste (naturalmente) em criar a tarefa. O código abaixo cria uma tarefa que imprime a hora atual:

 

public class Tarefa implements Job {

  public void execute (JobExecutionContext context)

      throws JobExecutionException

  {

      System.out.println (“Disparou:” + new Date());

  }

}

 

O segundo passo é criar o agendador. Para isso utilizamos a fábrica org.quartz.impl.StdSchedulerFactory, que cria uma instância do agendador a partir das propriedades descritas no arquivo quartz.properties (este arquivo será detalhado posteriormente):

 

Scheduler agendador =

  StdSchedulerFactory.getDefaultScheduler();

 

A seguir deve-se instanciar o detalhe da tarefa (um objeto org.quartz.JobDetail). O Quartz utiliza esse objetivo para armazenar os atributos da tarefa que será executada (incluindo eventuais parâmetros). Aqui utilizamos o JobDetail simplesmente para nomear a tarefa e atribuí-la a um grupo. O uso de nomes e grupos permite identificar unicamente a tarefa (ou o trigger) no agendador e possibilita a criação de categorias de tarefas e triggers. Como não existe necessidade de categorias a tarefa, usamos um grupo default:

 

JobDetail detalhe = new JobDetail(“Tarefa exemplo”,

   Scheduler.DEFAULT_GROUP,Tarefa.class);

 

Uma vez criado o agendador, devemos criar um trigger. Neste exemplo e construímos um trigger com nome “Trigger exemplo” que dispara a cada 10 segundos e inicia imediatamente. Para simplificar a criação e a configuração do trigger usamos a classe org.quartz.helpers.TriggerUtils, que oferece diversos métodos utilitários com esse propósito:

 

Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);

trigger.setName(“Trigger exemplo”);

trigger.setStartTime(new Date());

 

Agora é só agenda a tarefa e iniciar o agendador:

 

agendador.scheduleJob(detalhe,trigger);

agendador.start();

 

Até aqui vimos como manipular o agendamento via programação, codificando a tarefa e o trigger. O Quartz também permite que as tarefas sejam configuradas de forma declarativa em um arquivo XML. Utilizando essa estratégia, é possível modificar o agendamento das tarefas sem precisar alterar o código da aplicação.

Na próxima seção veremos como configurar o framework tanto na forma programática como na declarativa, e como utilizá-lo em container web. Apesar de o Quartz poder ser usado indistintamente em ambientes Java SE e EE, sem dúvida o uso no ambiente corporativo é mais comum e merece maior atenção. A configuração do Java SE não apresenta diferenças substanciais e poderá ser feita pelo próprio leitor a partir dos exemplos apresentados aqui.

 

Preparação inicial

Antes de iniciar o uso do Quartz, é necessário configurar o ambiente de desenvolvimento. Para este artigo usamos o JBoss 4.0.4 e o Eclipse 3.2. Como a geração dos pacotes e o deployment da aplicação são feitos através do Ant, qualquer IDE que ofereça suporte ao Ant pode ser utilizada.

O download do Quartz pode ser feito em opensymphony.com/quartz/download.action. Ao escrever este artigo, a versão mais recente do framework era 1.5.2, disponível no arquivo quartz-1.5.2.zip. Este ZIP inclui todas as bibliotecas necessárias, além dos javadocs. Após descompactar o arquivo, é necessário referenciar a biblioteca do Quartz (quartz-all-1.5.2.jar) no seu projeto.

 

Um exemplo completo: Quartz no container web

Em uma aplicação web, as configurações do Quartz normalmente são carregadas através de um servlet, que é configurado para iniciar junto com a aplicação. Apesar de essa ser a opção mais comum, também é possível usar o utilitário em conjunto com outros frameworks, como o Struts (para mais detalhes veja o quadro “Integrando Quartz e Struts”).

O Quartz oferece uma vasta gama de tarefas, aplicáveis às mais diversas situações. Para facilitar o entendimento do exemplo vamos separar as tarefas do Quartz em duas categorias: tarefas comuns e tarefas EJB.

Em uma tarefa comum toda lógica que se deseja realizar é codificado em uma classe que implementa a interface org.quartz.Job, conforme mostrado nos exemplos anteriores. Já em uma tarefa EJB, a lógica reside em um EJB, que é executado a partir de uma classe especial do Quartz: org.quartz.jobs.ee.ejb.EJBInvokerJob.

Nas próximas seções, descreveremos mais três possibilidades para configuração e utilização do Quartz através se servlets, cobrindo todas as opções possíveis. São elas:

  • Configuração declarativa e tarefa comum;
  • Configuração declarativa e tarefa EJB;
  • Configuração programática e tarefa EJB.

 

O quadro “Entendendo a aplicação de exemplo” detalha a estrutura dessa aplicação (que demonstra as três configurações) e o procedimento de build adotado para geração. Todos os arquivos da aplicação de exemplo estão disponíveis para download no site da Java Magazine.

 

Configurando uma tarefa simples ou q

Veja na Listagem 1 a classe ConfiguradorServlet, que é responsável pela configuração do Quartz. Como sabemos, o método init() de um servlet é disparado automaticamente pelo container web sempre que o servlet é colocado em serviço. Usaremos este método para configurar e iniciar o Quartz.

 

Ø       ...

Quer ler esse conteúdo completo? Tenha acesso completo