For most users, the JobStores supplied out-of-the-box will be sufficient. When your application doesn't require state to be maintained between restarts, RAMJobStore should be your first choice. It's fast, easy to set up, and as painless as can be. On the other hand, if you do need to maintain Scheduler state between restarts and you are using a database or have access to a database, using one of the JDBC JobStores is probably your best choice.
So what happens if you need a totally different type of JobStore? You're going to need to create a new type. This section discusses several approaches and offers ideas for how you can create a new JobStore when the provided solutions just don't fill the need.
Implementing the JobStore Interface
Regardless of whether they use a database, a file system, or even just memory, all JobStores must implement the JobStore interface. New JobStores that you create are no exception. Looking back through this chapter, you can see that RAMJobStore directly implements the JobStore interface, the JDBC JobStores subclass JobStoreSupport, which itself implements the JobStore interface.
The JobStore interface has 40 methods that must be implemented by any JobStore implementation, yours included. How you implement those methods depends entirely on the type of JobStore that you are building. That doesn't mean that your JobStore will have only 40 methods; this is just the minimum that the interface requires. These 40 methods represent the public contract between a JobStore and the Scheduler.
Let's pick one of the methods and talk about it for a second. Let's pick the JobStore interface method:
public void schedulerStarted() throws SchedulerException ;
The Scheduler calls the JobStore's schedulerStarted() method to inform the JobStore that the Scheduler has been started. If you look at the implementation in RAMJobStore, you can see that nothing is done inside this method for this implementation:
public void schedulerStarted() throws SchedulerException { // nothing to do }
However, if you look at the implementation for the two JDBC JobStores, you can see that some work has to be carried out when the Scheduler is first started:
public void schedulerStarted() throws SchedulerException { if (isClustered()) { clusterManagementThread = new ClusterManager(this); clusterManagementThread.initialize(); } else { try { recoverJobs(); } catch (SchedulerException se) { throw new SchedulerConfigException( "Failure occurred during job recovery.", se); } } misfireHandler = new MisfireHandler(this); misfireHandler.initialize(); }
Each JobStore implementation will be unique, and the functionality that is carried out within the interface method will vary. If you are serious about creating your own JobStore, you should review the source code for RAMJobStore to fully understand the responsibilities a JobStore has. The RAMJobStore should be used as a guide for any custom JobStore you need.
Scheduling in the Enterprise
Getting Started with Quartz
Hello, Quartz
Scheduling Jobs
Cron Triggers and More
JobStores and Persistence
Implementing Quartz Listeners
Using Quartz Plug-Ins
Using Quartz Remotely
Using Quartz with J2EE
Clustering Quartz
Quartz Cookbook
Quartz and Web Applications
Using Quartz with Workflow
Appendix A. Quartz Configuration Reference