问题
i have an quartz job in my web-application, which is started by an servlet. When i redeploy my application i get following message
[DefaultQuartzScheduler_Worker-5] but has failed to stop it. This is very likely to create a memory leak
Also in production we have the problem that the tomcat-server doesn't stop after ./shutdown.sh, so that we have to kill the process. In my opinion it depence on the quartz job, that can't stop.
How can i stop the quartz job by redeploy my application or shutdown the server?
I use tomcat 7, quartz 2.1.6 ...
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(XYZJob.class).withIdentity("job1", "group1").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1")
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 1 * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
As you can see my job starts one time per day. I don't see an point where i can check an flag, to cancel the job.
回答1:
My solution was to change my configuration. I created an quartz.properties
org.quartz.scheduler.instanceName = XYZJob
org.quartz.threadPool.threadCount = 1
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
a quartz-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData
http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version="1.8">
<schedule>
<job>
<name>XYZJob</name>
<group>XYZGroup</group>
<description>Check the contracts idle period</description>
<job-class>com.test.job.cron.XYZJob</job-class>
</job>
<trigger>
<cron>
<name>CronTriggerName</name>
<job-name>XYZJob</job-name>
<job-group>XYZGroup</job-group>
<!-- It will run every day at 1 am -->
<cron-expression>0 0 1 * * ?</cron-expression>
</cron>
</trigger>
</schedule>
and use the QuartzInitializerServlet in my web.xml
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
<init-param>
<param-name>config-file</param-name>
<param-value>quartz.properties</param-value>
</init-param>
<init-param>
<param-name>shutdown-on-unload</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>start-scheduler-on-load</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
After shutdown my Tomcat, i get the following message
INFO: QuartzInitializer: Quartz Scheduler successful shutdown.
回答2:
Your job must check regularly (for example, in each iteration), if a shutdown is in progress. It's up to you to implement this correctly in your job. Neither Quartz nor Tomcat can help here (how should they stop a thread?).
You could set a flag in a ServletContextListener
, method contextDestroyed
.
If the flag is set, the job must finish as soon as possible.
Quartz threads otherwise survive your web application's life time! So an update of your web application does not guarantee that jobs are terminated. I have had zombie jobs waking up "suddenly", right after a new deployment. This is one of the few cases where you just don't believe your log files.
This is why you have to kill
Tomcat, because there are running threads which have not been created by Tomcat.
来源:https://stackoverflow.com/questions/17394541/java-quartz-memory-leak-message