Simple Spring Quartz Web App with Maven and Eclipse

Simple Spring Quartz Web App with Maven and Eclipse

1. Create a Maven Web App project with Eclipse

File -> New -> Project -> Other -> Maven Project ->

Next -> Next ->

You should be at the Select Archtype Screen.

Type “webapp” (without the quotes) in the “filter” textbox.
Select the archtype with group Id: org.apache.maven.archtypes
and artifact id: maven-archtype-webapp.

Next -> Type whatever floats your boat for you Group Id and Artifact Id on the next screen:

-> Finish

2. Add needed dependencies to pom.xml. 

You are going to need all the listed dependencies, here is my pom:

<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>boyko</groupId>
<artifactId>batch-example</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>batch-example Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.opensymphony.quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
<build>
<finalName>batch-example</finalName>
</build>
</project>

3. Add Spring to your web app.

Add Spring’s ContextLoaderListener and the contextConfigLocation to web.xml.

This is my 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>
<display-name>Archetype Created Web Application</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

4. Create applicationContext.xml under src/main/resources

Right click on the project -> New -> Other -> XML file

5. Create src/main/java source folder

Right click on the project -> New -> Other -> Source Folder

6. Create the job

Create a package under src/main/java

Create a class that would be your Spring Batch job.

Here is what mine looks like:

package boyko;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class SampleJob {

public void sampleJobMethod() {

DateFormat dateFormat = new SimpleDateFormat(“dd/MM/yyyy hh:mm:ss”);

System.out.println(“Invoked on ” + dateFormat.format(System.currentTimeMillis()));
}
}

7. Add all needed configuration in applicationContext.xml

The final version of my specific applicationContext.xml is at the end of this section, but here are the additions step-by-step

7.1. Add the Job

<bean id=”sampleJob” class=”boyko.SampleJob” />

7.2. Create a Job Spring Quartz Bean and associate it with the Job and the Job method

<bean id=”sampleJobBean”
class=”org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean”>
<property name=”targetObject” ref=”sampleJob” />
<property name=”targetMethod” value=”sampleJobMethod” />
</bean>

7.3. Create a trigger

<bean id=”sampleJobTrigger” class=”org.springframework.scheduling.quartz.SimpleTriggerBean”>
<property name=”jobDetail” ref=”sampleJobBean” />
<property name=”repeatInterval” value=”10000″ />
<property name=”startDelay” value=”3000″ />
</bean>

7.4. Create a scheduler and associate it with the Job Bean and the Trigger

<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
<property name=”jobDetails”>
<list>
<ref bean=”sampleJobBean” />
</list>
</property>
<property name=”triggers”>
<list>
<ref bean=”sampleJobTrigger” />
</list>
</property>
</bean>

The numbers in trigger mean that the job will run for first time 3 seconds after app starts, then it will run every 10 seconds.

Here is the entire applicationContext.xml:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd”>

<bean id=”sampleJob” class=”boyko.SampleJob” />

<bean id=”sampleJobBean”
class=”org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean”>
<property name=”targetObject” ref=”sampleJob” />
<property name=”targetMethod” value=”sampleJobMethod” />
</bean>

<bean id=”sampleJobTrigger” class=”org.springframework.scheduling.quartz.SimpleTriggerBean”>
<property name=”jobDetail” ref=”sampleJobBean” />
<property name=”repeatInterval” value=”10000″ />
<property name=”startDelay” value=”3000″ />
</bean>

<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
<property name=”jobDetails”>
<list>
<ref bean=”sampleJobBean” />
</list>
</property>
<property name=”triggers”>
<list>
<ref bean=”sampleJobTrigger” />
</list>
</property>
</bean>

</beans>

That should be that.

Run it on whatever server you prefer( I run on Tomcat 7 – right click on project -> Run On Server -> Tomcat 7) and you should see the sysouts in the console:

Attached is the sample. You could import it as an eclipse project after you unzip it and give a try on your own.

boyko-spring-batch-example

And here is an identical example which uses Cron Trigger and JobDetailBean:

boyko-cron-jobDetailBean-example

Update:12-11-2013: There’s a better way to do a scheduled job these days. Use the @Scheduled annotation.