views:

724

answers:

2

I'm using the Spring Quartz integration, and every time I try to shut down Tomcat, the Quartz processes fail to shut down. This is the stack trace:

Exception in thread "org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread" 
        java.lang.NullPointerException
    at org.apache.commons.logging.LogFactory.getCachedFactory(LogFactory.java:979)
    at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:435)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
    at org.quartz.core.QuartzSchedulerThread.getLog(QuartzSchedulerThread.java:475)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:404)

Has anyone seem this before?

+1  A: 

Do you have a copy of commons-logging packaged inside your WAR? If so, there may be an odd interaction between the copy that comes as part of Tomcat, and the copy that's in your WAR. Try removing the WAR copy and see if that helps.

skaffman
This did fix my initial problem of a NullPointerException - but it was replaced with a ClassNotFound exception... so I voted you up, but Matt's answer actually solved the rest of the problem so I'm choosing it. Thanks!
stevedbrown
+5  A: 

If you look at SchedulerFactoryBean, it has a property named waitForJobsToCompleteOnShutdown. When the Spring ApplicationContext receives the request to shut down, it tells the Quartz Scheduler to shut down, conditionally telling it to wait for all jobs to complete before shutting down.

But, Spring can only process the request to shutdown (and tell Quartz) to shutdown if it is notified of the Tomcat context being disposed. How are you using Spring within Tomcat? Do you have a ServletContextListener registered to call applicationContext.destroy() ?

The actual NPE is probably caused by Tomcat setting all static references within the classLoader that your application runs in to null on shutdown. It does this to help prevent any memory leaks during recycling/restarts of Tomcat. But, if you have threads that live on within the Tomcat container that are still running (because they were not properly shutdown, such as your Quartz threads), then you will see errors when the code within that thread (such as the code within your Quartz thread that tries to gain access to it's logger - which is likely kept as static) tries to access any static references that have been nulled out.

matt b