Spring调度程序关闭错误

在tomcat容器中开发基于SPRING的调度程序期间,我总是在取消部署webapp或shutdown服务器时获得此logoutput:

Apr 28, 2010 4:21:33 PM org.apache.catalina.core.StandardService stop INFO: Stopping service Catalina Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] but has failed to stop it. This is very likely to create a memory leak. Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2] but has failed to stop it. This is very likely to create a memory leak. Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3] but has failed to stop it. This is very likely to create a memory leak. Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] but has failed to stop it. This is very likely to create a memory leak. Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-5] but has failed to stop it. This is very likely to create a memory leak. . . . SEVERE: A web application created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [Prototype beans currently in creation]) and a value of type [null] (value [null]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed. Apr 28, 2010 4:21:34 PM org.apache.coyote.http11.Http11Protocol destroy INFO: Stopping Coyote HTTP/1.1 on http-8606 

我怎样才能解决这个问题?

谢谢stevedbrown

我将这个监听器添加到我的webapp中

 public class ShutDownHook implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { BeanFactory bf = (BeanFactory) ContextLoader.getCurrentWebApplicationContext(); if (bf instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext)bf).close(); } } @Override public void contextInitialized(ServletContextEvent arg0) { } } 

和我的web.xml

  pkg.utility.spring.ShutDownHook  

但错误仍然存​​在。

弹簧配置:

                 

您需要添加一个关闭钩子 – 请参阅在Spring 2.5中注册一个关闭钩子 。

在您的情况下,您可能应该向webapp添加一个上下文侦听器来执行此操作(侦听器+实现类的web.xml条目)。

使用close,这是最简单的。

 ((YourClass)yourObject).close(); 

Imho这是石英调度器的一个问题。 我提交了一个错误https://jira.terracotta.org/jira/browse/QTZ-192 。 作为一种解决方法,Colin Peters建议的sleep()解决方案适合我。 为了不触发关闭两次,也可以将睡眠添加到Spring的SchedulerFactoryBean:

 import org.quartz.SchedulerException; import org.springframework.scheduling.quartz.SchedulerFactoryBean; public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean{ @Override public void destroy() throws SchedulerException { super.destroy(); // TODO: Ugly workaround for https://jira.terracotta.org/jira/browse/QTZ-192 try { Thread.sleep( 1000 ); } catch( InterruptedException e ) { throw new RuntimeException( e ); } } } 

这是我的解决方案,因为我找到的在线工作都没有。 这是专门用Spring和Tomcat关闭Quartz调度程序

我的解释如下: http : //forum.springsource.org/showthread.php?34672-Quartz-doesn-t-shutdown&p = 370060#post370060

基本上问题似乎是Quartz没有足够的时间来干净地关闭,而waitForJobsToCompleteOnShutdown参数似乎没有帮助。 所以我在webapp中实现了一个自定义关闭监听器,获取对调度程序的引用并手动关闭它。 然后等待1秒再继续。

 public class ShutDownHook implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { try { // Get a reference to the Scheduler and shut it down WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); Scheduler scheduler = (Scheduler) context.getBean("quartzSchedulerFactory"); scheduler.shutdown(true); // Sleep for a bit so that we don't get any errors Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } @Override public void contextInitialized(ServletContextEvent arg0) { } 

确保线程终止的唯一方法是中断并加入它们。

这可以通过实现org.quartz.InterruptableJob来完成,如问题的答案中所述如何防止石英中的内存泄漏[?]