This is an expansion on jhouse's answer. I can't put this code in a comment :-(.
Specifically, you need to add a ServletContextListener to your web.xml:
<listener>
<listener-class>org.whatever.MyListener</listener-class>
</listener>
Then in the implementation, in the context contextDestroyed() method, sleep for 10 seconds (1 second wasn't enough for my app). It should look something like this:
public class MyListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent arg0) {}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
try {
// This can't use logging because it's (hopefully) been shut down by now.
System.out.println("Sleep for a bit so that we don't get any errors about Quartz threads not being shut down yet. ");
// For more info, see here: http://stackoverflow.com/questions/2730354/spring-scheduler-shutdown-error
Thread.sleep(10 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I had no need for calling the scheduler shutdown methods (it was clear they were already being called somewhere, maybe 'cuz I'm using Spring). All I needed to do was add the wait and then they all went away (except a FileWatchdog Log4j thread and some other MySQL thread, but those are different questions).