2

저는 Spring Quartz 통합을 사용하고 있으며 Tomcat을 종료 할 때마다 Quartz 프로세스가 종료되지 않습니다. 이것은 스택 추적입니다 :Quartz와 Spring을 사용하는 NullPointerException

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) 

누군가가 이것을 전에 보입니까?

답변

7

SchedulerFactoryBean을 보면 waitForJobsToCompleteOnShutdown이라는 속성이 있습니다. Spring ApplicationContext는 종료 요청을 받으면 Quartz Scheduler에게 종료하도록 지시하고, 종료하기 전에 모든 작업이 완료 될 때까지 대기하도록 조건부로 지시한다.

하지만 Spring은 톰캣 컨텍스트가 삭제되었다는 통지를 받으면 시스템 종료 (콰이어어에게 셧다운 요청) 만 처리 할 수있다. Tomcat에서 Spring을 어떻게 사용하고 있습니까? applicationContext.destroy()으로 전화하기 위해 ServletContextListener이 등록되어 있습니까?

실제 NPE는 응용 프로그램이 종료 될 때 null으로 실행되는 classLoader 내의 모든 static 참조를 Tomcat이 설정하여 발생했을 수 있습니다. Tomcat을 재사용/재시작 할 때 메모리 누수를 방지하기 위해이 작업을 수행합니다. 하지만 Tomcat 컨테이너에서 실행중인 스레드가 Quartz 스레드와 같이 제대로 종료되지 않았기 때문에 실행중인 스레드가 있으면 해당 스레드 내의 코드 (예 : Quartz 스레드의 코드와 같은)가 표시 될 때 오류가 표시됩니다. static으로 유지 될 가능성이있는 로거에 액세스하려고하는 석영 스레드는 제외 된 정적 참조에 액세스하려고 시도합니다.

+0

어디서이 문서를 찾을 수 있습니까? –

+0

"tomcat context reload static classloader"와 같은 것을 Google에 게재 할 수 있습니다. Tomcat, Spring, Hibernate 및 log4j를 콘서트에서 사용할 때 메모리 누수에 대한 정보를 찾으려고 할 때 많은 것을 읽었던 것을 기억합니다. 그래서 Google도이 콤보를 사용합니다. –

1

WAR 내에 commons-logging 패키지가 있습니까? 그렇다면 Tomcat에 포함 된 사본과 WAR에있는 사본간에 이상한 상호 작용이있을 수 있습니다. WAR 복사본을 제거하고 도움이되는지 확인하십시오.

+0

이것은 NullPointerException의 초기 문제를 해결했지만 ClassNotFound 예외로 바뀌 었습니다 ... 그래서 당신의 의견을 표결했지만 매트의 대답은 나머지 문제를 실제로 풀어서 선택했습니다. 감사! – stevedbrown