Reputation: 34537
We are trying to do what appears to be a very straightforward thing, but it is not working, and solutions I find online seem to complex for something so basic, so I feel like I should ask again. We have a Spring web application running under tomcat. We added Quartz scheduler to it:
<bean id="myScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="transactionManager" ref="myTransactionManager"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="autoStartup" value="true"/>
<property name="jobFactory">
<bean class="AutowiringSpringBeanJobFactory"/>
</property>
<!-- NOTE: Must add both the jobDetail and trigger to the scheduler! -->
<property name="jobDetails">
<list>
<ref bean="jobDetailAutoSendPublishedReport" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTriggerAutoSendPublishedReport"/>
</list>
</property>
<property name="quartzProperties">
<props>
<!-- Main Scheduler Properties For A Clustered Scheduler -->
<prop key="org.quartz.scheduler.instanceName">test</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
<prop key="org.quartz.scheduler.idleWaitTime">60000</prop>
<!-- ThreadPool -->
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">5</prop>
<!-- Shutdown Hook Plugin -->
<!--prop key="org.quartz.plugin.shutdownhook.class">org.quartz.plugins.management.ShutdownHookPlugin</prop>
<prop key="org.quartz.plugin.shutdownhook.cleanShutdown">true</prop-->
<!-- JDBC JobStore -->
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>
<prop key="org.quartz.jobStore.useProperties">false</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">300000</prop>
<prop key="org.quartz.jobStore.misfireThreshold">300000</prop>
</props>
</property>
</bean>
And then when I try to shutdown tomcat I get the following error and tomcat fials to shutdown:
appears to have started a thread named [DefaultQuartzScheduler_QuartzSchedulerThread] but has failed to stop it. This is very likely to create a memory leak. Jan 27, 2015 1:09:35 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
My fix is to add the following to web.xml:
<!-- Start Quartz -->
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:start-on-load</param-name>
<param-value>false</param-value> <!-- let spring handle starting -->
</context-param>
<!-- End of Quartz -->
Upvotes: 2
Views: 3082
Reputation: 12453
In the docs it reads:
If you are using the org.quartz.ee.servlet.QuartzInitializerListener to fire up a scheduler in your servlet container, its contextDestroyed() method will shutdown the scheduler when your application is undeployed or the application server shuts down.
Maybe you can add this listener too.
Upvotes: 2