So, I've ran into a rather nasty gotcha around Spring's support for scheduling Runnables (as opposed to org.quartz.Job instances) with Quartz via DelegatingJob. Specifically, it seems that this is only usable when you're not persisting jobs to a database.

The problem is that Spring's JobDetailBean.getJobClass() returns the Runnable rather than DelegatingJob. This seems intuitive but the result is that the class name of the Runnable is what winds up being written into the Quartz table qrtz_job_details. While again this would seem like desired behavior, the problem happens when Quartz tries to rehydrate that database record into a JobDetail (not JobDetailBean!). JobDetail.setJobClass() throws an exception because the class doesn't implement org.quartz.Job.

I've worked around this in our application by storing the Runnable job class name in the JobDataMap (which gets serialized to the db), and writing a custom JobFactory that pulls it back out and instantiates it rather than what Quartz thinks the job class is. It would be nice if a solution like this could get into Spring, but even in lieu of that, I think this gotcha is nasty enough that it should be called out in the docs.