I want to create a scheduler with Quartz 2.2 in java dynamic web application. I am new to this task. I tried all the tutorials around the web. I trying context listener method to initialize the scheduler. It doesn't seem like working. The hello world program only works in general java application. for web application its looks tricky.
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."); } }
servlet.java package 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>
I am using maven web app archtype.
If you are using a typical project in eclipse, the most basic example has a structure similar to:
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
Where the code of each of the files is as follows:
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>
The job is executed every 5 minute(s) (see the expression 0 0/5 * 1/1 * ? *
in the cron-expression
tag). If you want another expression, you can build it with 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>
If you are using Maven, the structure for the same project is:
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
And the file 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>
* This requires Servet 3.0+ (Tomcat 7+, Glassfish 3+, JBoss AS 7)
You only need two files: TestJob.java
from the previous example and the following listener:
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); } } }
To avoid conflicts, do not set the default listener in the web.xml
at the same time. With this last example, the default number of threads is 10. Since the scheduler started in stand-by mode, it is necessary to call scheduler.start();
. The "simple"
identity is optional, but you can use it for reschedule the job (That's great!). e.g.:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With