quartz java maven tomcat7 quartz-scheduler

java - Ejemplo simple para Quartz 2.2 y Tomcat 7



quartz java (1)

Quiero crear un programador con Quartz 2.2 en la aplicación web dinámica java. Soy nuevo en esta tarea. Intenté todos los tutoriales en la web. Estoy intentando el método de escucha contextual para inicializar el programador. No parece que funcione. El programa hello world solo funciona en la aplicación java en general. para la aplicación web parece complicado.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>test.ananth</groupId> <artifactId>test-app</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>test-app Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>servlet-api</artifactId> <version>6.0.30</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>test-app</finalName> </build>

quartz.properties:

#org.quartz.scheduler.instanceName = MyScheduler org.quartz.threadPool.threadCount = 3 org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore # Main Quartz configuration org.quartz.scheduler.skipUpdateCheck = true org.quartz.scheduler.instanceName = MyQuartzScheduler org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool #org.quartz.threadPool.threadCount = 5

HelloJob.java:

package com.test; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class HelloJob implements Job { public HelloJob() { } public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello! HelloJob is executing."); } }

paquete servlet.java com.test;

import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; public class MyServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1567185871113714035L; public void init(ServletConfig cfg) { String key = "org.quartz.impl.StdSchedulerFactory.KEY"; ServletContext servletContext = cfg.getServletContext(); StdSchedulerFactory factory = (StdSchedulerFactory) servletContext .getAttribute(key); // Scheduler quartzScheduler = factory.getScheduler("MyQuartzScheduler"); Scheduler sched; try { sched = factory.getScheduler("MyQuartzScheduler"); //sched = factory.getScheduler();//MyQuartzScheduler sched.start(); // define the job and tie it to our HelloJob class JobDetail job = newJob(HelloJob.class).withIdentity("myJob", "group1").build(); // Trigger the job to run now, and then every 40 seconds Trigger trigger = newTrigger() .withIdentity("myTrigger", "group1") .startNow() .withSchedule( simpleSchedule().withIntervalInSeconds(4) .repeatForever()).build(); // Tell quartz to schedule the job using our trigger sched.scheduleJob(job, trigger); } catch (SchedulerException e) { e.printStackTrace(); } } }

Web.xml:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <context-param> <context-param> <param-name>quartz:shutdown-on-unload</param-name> <param-value>false</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-scheduler-on-load</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>quartz:config-file</param-name> <param-value>/WEB-INF/quartz.properties</param-value> </context-param> <listener> <listener-class> org.quartz.ee.servlet.QuartzInitializerListener </listener-class> </listener> <listener> <listener-class>com.test.ApplicationStartup</listener-class> </listener> <display-name>Archetype Created Web Application</display-name> </web-app>

Estoy usando maven web app archtype.


Contenido

  • Proyecto Eclipse
  • Con Maven
  • XML-Less

Proyecto Eclipse

Si está utilizando un proyecto típico en eclipse, el ejemplo más básico tiene una estructura similar a:

C:. | +---src | | log4j.dtd | | log4j.xml | | quartz.properties | | quartz_data.xml | | | /---org | /---paulvargas | /---test | /---quartz | TestJob.java | /---WebContent /---WEB-INF | web.xml | /---lib jta-1.1.jar log4j-1.2.17.jar quartz-2.1.5.jar slf4j-api-1.6.5.jar slf4j-log4j12-1.6.5.jar

Donde el código de cada uno de los archivos es el siguiente:

web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <listener> <listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class> </listener> </web-app>

quartz.properties

# ----------------------------- Threads --------------------------- # # How many jobs can run at the same time? org.quartz.threadPool.threadCount=5 # ----------------------------- Plugins --------------------------- # # Class to load the configuration data for each job and trigger. # In this example, the data is in an XML file. org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin

quartz_data.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="1.8"> <schedule> <job> <name>TestJob</name> <job-class>org.paulvargas.test.quartz.TestJob</job-class> </job> <trigger> <cron> <name>TestJob</name> <job-name>TestJob</job-name> <cron-expression>0 0/5 * 1/1 * ? *</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>

El trabajo se ejecuta cada 5 minutos (vea la expresión 0 0/5 * 1/1 * ? * En la etiqueta cron-expression ). Si desea otra expresión, puede compilarla con http://www.cronmaker.com/

TestJob.java

package org.paulvargas.test.quartz; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class TestJob implements Job { @Override public void execute(final JobExecutionContext ctx) throws JobExecutionException { System.out.println("Executing Job"); } }

log4j.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd" > <log4j:configuration> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p (%c.java:%L).%M - %m%n"/> </layout> </appender> <root> <priority value="TRACE" /> <appender-ref ref="STDOUT"/> </root> </log4j:configuration>

Con Maven

Si está utilizando Maven, la estructura para el mismo proyecto es:

C:. | pom.xml | /---src /---main +---java | /---org | /---paulvargas | /---test | /---quartz | TestJob.java | +---resources | log4j.dtd | log4j.xml | quartz.properties | quartz_data.xml | /---webapp | index.jsp | /---WEB-INF web.xml

Y el archivo pom.xml :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>test</groupId> <artifactId>BasicQuartz</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>BasicQuartz</name> <url>http://maven.apache.org</url> <dependencies> <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> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project>

Sin XML

* Esto requiere Servet 3.0+ (Tomcat 7+, Glassfish 3+, JBoss AS 7)

Solo necesita dos archivos: TestJob.java del ejemplo anterior y el siguiente oyente:

import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener; import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.ee.servlet.QuartzInitializerListener; import org.quartz.impl.StdSchedulerFactory; @WebListener public class QuartzListener extends QuartzInitializerListener { @Override public void contextInitialized(ServletContextEvent sce) { super.contextInitialized(sce); ServletContext ctx = sce.getServletContext(); StdSchedulerFactory factory = (StdSchedulerFactory) ctx.getAttribute(QUARTZ_FACTORY_KEY); try { Scheduler scheduler = factory.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(TestJob.class).build(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simple").withSchedule( CronScheduleBuilder.cronSchedule("0 0/1 * 1/1 * ? *")).startNow().build(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } catch (Exception e) { ctx.log("There was an error scheduling the job.", e); } } }

Para evitar conflictos, no configure el detector predeterminado en el web.xml al mismo tiempo. Con este último ejemplo, el número predeterminado de subprocesos es 10. Como el planificador se inició en modo de espera, es necesario llamar a scheduler.start(); . La identidad "simple" es opcional, pero puede usarla para reprogramar el trabajo (¡Eso es genial!). p.ej:

ServletContext ctx = request.getServletContext(); StdSchedulerFactory factory = (StdSchedulerFactory) ctx.getAttribute(QuartzListener.QUARTZ_FACTORY_KEY); Scheduler scheduler = factory.getScheduler(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simple").withSchedule( CronScheduleBuilder.cronSchedule(newCronExpression)).startNow().build(); Date date = scheduler.rescheduleJob(new TriggerKey("simple"), trigger);