Configuring Quartz 2 with Spring in clustered mode
Aligning the stars to configure Quartz 2.1.7 to work with Spring 3.1.3 in a cluster was surprisingly complicated. The main idea is to run jobs to fire only once per cluster, not once per server, while still providing beans from the Spring managed context and using the latest version of Quartz. The documentation consists essentially of a number of blog posts and stackoverflow answers. So here is one final and (hopefully) more comprehensive summary of the process.
For the TL;DR version, just see the full github gist.
In Quartz.properties we'll want to set useProperties=true so that data persisted to
the DB is in String form instead of Serialized Java objects. But unfortunately the Spring
3.1.x CronTriggerFactoryBean sets a jobDetails property as a Java object, so Quartz will
complain that the data is not a String. We'll need to create our own
PersistableCronTriggerFactoryBean to get around this issue (similar to this
blog post and forum
discussion).
Additionally, in our Spring config the SchedulerFactoryBean will need to set both the
triggers
and the jobDetails objects. We also setup the scheduler to use Spring's dataSource
and transactionManager. And notice that durability=true must be set on each
JobDetailFactoryBean.
By default you cannot use Autowired capabilities in the Quartz Jobs, but this can be
easily setup with a AutowiringSpringBeanJobFactory.
You'll also notice that we cannot use MethodInvokingJobDetailFactoryBean
because it is not serializable, so we need to create our own Job class that extends
QuartzJobBean. If your services are secured by Acegi or Spring Security, you will also need to
register an authenticated quartzUser object with the security context.
And finally, we'll want to test that the trigger's Cron expression actually fires
when we want it to. Here is an example test case that pulls the cronExpression from
configuration and tests that it fires correctly on 2 consecutive days:
Hopefully this helps others in configuring an enterprise-ready Quartz + Spring application to run jobs in a clustered server environment.
Cross-published on the Object Partners blog:
https://objectpartners.com/2013/07/09/configuring-quartz-2-with-spring-in-clustered-mode/