0

I've seen the following answer when looking for a way to handle schedule tasks in a self learning web app that I'm building. I'm using the latest version of Quartz and Tomcat 8.0.27 that is installed with Netbeans.

Simple example for Quartz 2.2 and Tomcat 7

XML-less

  • This requires Servet 3.0+ (Tomcat 7+, Glassfish 3+, JBoss AS 7)

You only need two files: TestJob.java from the previous example and the following listener:

As I'm not using Maven and don't want to use XML, I have some questions related to it, as I'm getting an error on running the code starting Tomcat.

I'm trying to run the task every twelve hours, at 08:30 and 20:30

The answer says not to

To avoid conflicts, do not set the default listener in the web.xml

But unless I set the Listener in the web xml of my application it does not run the job.

<listener> 
<listener-class>medsched.slisteners.MedSchedContextListener</listener-class> 
</listener>

Should this be the case, or am I misunderstanding this part of the answer?

The error I get, even using the interval of the highlighted answer, relates to the fact that Tomcat sees the thread running without stopping. It reports the following

18-Nov-2017 15:46:20.347 WARNING [http-nio-8084-exec-3]  org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads 
The web application [medsched] appears to have started a thread named  [DefaultQuartzScheduler_Worker-10] but has failed to stop it. 
This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)

Is there additional code I should be adding to prevent the error?

public class MedSchedContextListener extends QuartzInitializerListener{
private final static Logger LOG = LogManager.getLogger(MedSchedContextListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
    super.contextInitialized(sce);
    ServletContext ctx = sce.getServletContext();
    StdSchedulerFactory factory = (StdSchedulerFactory) ctx.getAttribute(QUARTZ_FACTORY_KEY);
    try {
        Scheduler scheduler = factory.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(MedSchedReminder.class).build();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simple").withSchedule(
                CronScheduleBuilder.cronSchedule("0 30 8,20 1/1 * ? *")).startNow().build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
    } catch (Exception e) {
        LOG.error("There was an error scheduling the job.", e);
    }
}

}

Edited web.xml section which now stops the error.

<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>

 <listener>
    <listener-class>medsched.slisteners.MedSchedContextListener</listener-class>
</listener>
Graham
  • 322
  • 4
  • 17

1 Answers1

1

According to source code of QuartzInitializerListener quartz was being shutdown but the waitOnShutdown flag is set to false, hence Tomcat didn't wait for quartz to finish before it shutdown so Tomcat decided that it had left threads running and complained.

Try to init the quartz:wait-on-shutdown to true in your listener configuration in addition to shutdown-on-unload property which default to true already (web.xml).

 <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>
Maxim Kirilov
  • 2,639
  • 24
  • 49
  • The code should utilize Quartz without any parameters in the web.xml. I did try your suggestion but the error persists – Graham Nov 18 '17 at 19:12
  • Please share your full web.xml. – Maxim Kirilov Nov 18 '17 at 19:27
  • Have added the web.xml, but my understanding of the last example in Simple example for Quartz 2.2 and Tomcat 7 would be that it should not need an entry in the web.xml file or a quartz properties file. – Graham Nov 18 '17 at 20:10
  • Have you read the listener documentation? It clearly states that: The init parameter 'quartz:wait-on-shutdown' has effect when 'quartz:shutdown-on-unload' is specified "true", and indicates whether you want scheduler.shutdown(true) called when the listener is unloaded (usually when the application server is being shutdown). Passing "true" to the shutdown() call causes the scheduler to wait for existing jobs to complete. Possible values are "true" or "false". The default is "false". – Maxim Kirilov Nov 18 '17 at 20:24
  • I have but the XML Less section of the question/answer I mention reads to me like its not required. The error appears on starting Tomcat. Again I'm learning this stuff from scratch. So if my understanding of the referenced question/answer is incorrect, please let me know – Graham Nov 18 '17 at 20:28
  • Ok have it sorted now. Thanks, edited web.xml to reflect changes – Graham Nov 18 '17 at 21:55