简体   繁体   English

Quartz & Spring 的 NullPointerException

[英]NullPointerException With Quartz & Spring

I'm using the Spring Quartz integration, and every time I try to shut down Tomcat, the Quartz processes fail to shut down.我正在使用 Spring Quartz 集成,每次我尝试关闭 Tomcat 时,Quartz 进程都无法关闭。 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?有没有人看过这个?

If you look at SchedulerFactoryBean, it has a property named waitForJobsToCompleteOnShutdown .如果您查看 SchedulerFactoryBean,它有一个名为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.当 Spring ApplicationContext 收到关闭请求时,它告诉 Quartz Scheduler 关闭,有条件地告诉它在关闭之前等待所有作业完成。

But, Spring can only process the request to shutdown (and tell Quartz) to shutdown if it is notified of the Tomcat context being disposed.但是,如果 Tomcat 上下文被处理,Spring 只能处理关闭请求(并告诉 Quartz)关闭。 How are you using Spring within Tomcat?您如何在 Tomcat 中使用 Spring? Do you have a ServletContextListener registered to call applicationContext.destroy() ?您是否注册了ServletContextListener来调用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.实际的 NPE 可能是由于null在关闭时将应用程序运行的类加载器中的所有static引用设置为 null 引起的。 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.它这样做是为了帮助防止在 Tomcat 的回收/重新启动期间发生任何 memory 泄漏。但是,如果 Tomcat 容器中的线程仍在运行(因为它们没有正确关闭,例如您的 Quartz 线程),那么您当该线程中的代码(例如您的 Quartz 线程中试图访问其记录器的代码 - 可能保留为static )尝试访问任何已被取消的 static 引用时,将会看到错误。

Do you have a copy of commons-logging packaged inside your WAR?您的 WAR 中是否有打包的 commons-logging 副本? 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.如果是这样,作为 Tomcat 一部分的副本与 WAR 中的副本之间可能存在奇怪的交互。 Try removing the WAR copy and see if that helps.尝试删除 WAR 副本,看看是否有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM