In my steps below, I’m using Grails 2.0.0 and Quartz 2.1.1. I’m also connecting to a local DB2 database.
1. Run “grails clean” on your application.
2. Add the “quartz-all-2.1.1.jar” and “c3p0-0.9.1.1.jar” (in the lib folder of your Quartz download) to your lib directory.

3. Right click on your Grails project and chose “Grails Tools -> Refresh Dependencies” (Alt+G, R)
* Note: You will need run steps 1 – 3 in order to get Grails to link the dependencies.

4. Add your Quartz.properties file to your “conf” directory (or somewhere else on your classpath). Here’s the Quartz.properties file I used (you’ll need to change the username and password).
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver = com.ibm.db2.jcc.DB2Driver
org.quartz.dataSource.myDS.URL = jdbc:db2://localhost:50001/BATCH
org.quartz.dataSource.myDS.user = <some user>
org.quartz.dataSource.myDS.password = <some password>
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
5. In your Config.groovy file, add or modify you “grails.config.locations” property. Here’s what I added:
grails.config.locations = [
"classpath:conf/Quartz.properties"
]
6. I added the JobScheduler and HelloJob java classes to my src/java directory. These could be groovy or whatever, but I just stole the example from Quartz to get it working correctly.
JobScheduler.java
package sample.quartz.scheduler;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.CronScheduleBuilder.*;
import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
public class JobScheduler {
private static Logger log = Logger.getLogger(JobScheduler.class);
private static JobScheduler JOB_SCHEDULER = new JobScheduler();
private Scheduler scheduler = null;
public JobScheduler() {
}
public static JobScheduler getInstance() {
return JOB_SCHEDULER;
}
public void startup() {
try {
// and start it off
scheduler = StdSchedulerFactory.getDefaultScheduler();
System.out.println("NAME: " + scheduler.getSchedulerName());
scheduler.start();
// define the job and tie it to our HelloJob class
JobDetail job = newJob(HelloJob.class)
.withIdentity("job1", "group1")
.build();
// Trigger a job that repeats every 20 seconds
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(cronSchedule("0/20 * * * * ?"))
.build();
System.out.println("Starting Jobs");
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
scheduler.start();
} catch (SchedulerException se) {
se.printStackTrace();
}
}
public void shutdown() {
try {
scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
}
}
}
HelloJob.java
package sample.quartz.scheduler;
import java.util.Date;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
private static Logger log = Logger.getLogger(HelloJob.class);
public HelloJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("Hello! HelloJob is executing. " + new Date());
}
}
7. In your BootStrap.groovy file, add…
import sample.quartz.scheduler.JobScheduler
class BootStrap {
def init = { servletContext ->
JobScheduler.getInstance().startup()
}
def destroy = {
JobScheduler.getInstance().shutdown()
}
}
That’s it! Start your server. I tested it by running two servers. So,
grails -Dserver.port=8080 run-app
and then
grails -Dserver.port=8090 run-app
You will see that the first server to come up will run the HelloJob.java. I then tested the cluster by shutting off the first server. The second server picked up the scheduler (within 20 seconds, since that’s what was specified in the property file) and started running with it.
One problem I ran into trying to set this up was the error below. I had forgotten to c3po-0.9.1.1.jar along with quartz-all-2.1.1jar to the lib directory. Once I did that (and refreshed the dependencies), this error went away.
Issue:
ERROR context.GrailsContextLoader - Error executing bootstraps: java.lang.NoClassDefFoundError: com/mchange/v2/c3p0/ComboPooledDataSource
Hope that helps.