2

我正在使用 Spring Quartz 集成,每次尝试关闭 Tomcat 时,Quartz 进程都无法关闭。这是堆栈跟踪:

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)

以前有人这样看吗?

4

2 回答 2

7

如果您查看 SchedulerFactoryBean,它有一个名为waitForJobsToCompleteOnShutdown. 当 Spring ApplicationContext 收到关闭请求时,它告诉 Quartz Scheduler 关闭,有条件地告诉它等待所有作业完成后再关闭。

但是,Spring 只能处理关闭请求(并告诉 Quartz)关闭,如果它被通知 Tomcat 上下文被释放。您如何在 Tomcat 中使用 Spring?你有ServletContextListener注册电话applicationContext.destroy()吗?

实际的 NPE 可能是由于 Tomcat 将static应用程序null在关闭时运行的类加载器中的所有引用设置为造成的。它这样做是为了防止在 Tomcat 的回收/重新启动期间发生任何内存泄漏。但是,如果您的 Tomcat 容器中存在仍在运行的线程(因为它们没有正确关闭,例如您的 Quartz 线程),那么当该线程中的代码(例如您的试图访问它的记录器的 Quartz 线程 - 可能保留为static) 尝试访问已被清空的任何静态引用。

于 2009-06-17T20:58:35.007 回答
1

您的 WAR 中是否有一份公共日志记录的副本?如果是这样,则作为 Tomcat 一部分的副本与您的 WAR 中的副本之间可能存在奇怪的交互。尝试删除 WAR 副本,看看是否有帮助。

于 2009-06-17T20:56:17.883 回答