Announcement Announcement Module
Collapse
No announcement yet.
Quartz doesn't shutdown Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Quartz doesn't shutdown

    Spring 2.0.2
    Quartz 1.6.0
    Tomcat 5
    JDK 1.4.2_11

    I'm using Quartz in my web app. When I attempt to shutdown Tomcat, the Quartz threads don't shutdown. Here's my config:

    <beans>

    <bean name="logCacheStatisticsJob" class="org.springframework.scheduling.quartz.JobDe tailBean">
    <property name="jobClass" value="com.metavante.its.services.scheduling.quart z.LogCacheStatisticsJob" />
    <property name="jobDataAsMap">
    <map>
    <entry key="cacheRegistry">
    <ref bean="cacheRegistry"/>
    </entry>
    </map>
    </property>
    </bean>

    <bean id="cacheStatisticsCronTrigger" class="org.springframework.scheduling.quartz.CronT riggerBean">
    <property name="jobDetail" ref="logCacheStatisticsJob" />
    <!-- Every 2 minutes -->
    <property name="cronExpression" value="0 0/2 * * * ?" />
    <!-- Every 15 minutes -->
    <!-- <property name="cronExpression" value="0 0,15,30,45 * * * ?" /> -->
    </bean>

    <bean class="org.springframework.scheduling.quartz.Sched ulerFactoryBean" destroy-method="destroy">
    <property name="triggers">
    <list>
    <ref bean="cacheStatisticsCronTrigger" />
    </list>
    </property>
    </bean>

    </beans>


    I looked at the source code for Spring's SchedulerFactoryBean and I see where the scheduler should be shutting down, but it's not happening.

    /**
    * Shut down the Quartz scheduler on bean factory shutdown,
    * stopping all scheduled jobs.
    */
    public void destroy() throws SchedulerException {
    logger.info("Shutting down Quartz Scheduler");
    this.scheduler.shutdown(this.waitForJobsToComplete OnShutdown);
    }


    Any ideas how I can fix this?

  • #2
    Is there anything in the log to detail what it's doing? Have you tried attaching a remote debugger and having a look what the active threads are doing?

    Comment


    • #3
      Quartz doesn't shutdown

      Hope the above code will do the work..
      Code:
      <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
      	<property name="triggers">
      		<list>
      			<ref bean="TRIGGER" />
      		</list>
      	</property>
      
      	<property name="autoStartup"><value>true</value></property>
      	<property name="applicationContextSchedulerContextKey"><value>applicationContext </value></property>
      	<property name="waitForJobsToCompleteOnShutdown"><value>false</value></property>
      </bean>
      Regards,
      I.N.

      Comment


      • #4
        waitForJobsToCompleteOnShutdown=false is the default, not sure how that will help.

        Comment


        • #5
          Quartz wont shutdown in tomcat container

          Hi, I recently ran into this problem.
          I'm using the quartz.SchedulerFactoryBean but I'm not using the standard web contextloader, instead I'm using ClassPathXmlApplicationContext from my own singleton instantiated from my own servlet in order to get spring up.
          I'm doing this because my code can then easilly be all packed up into a jar file and used in a servlet container or as a standalone app very easilly. as a standalone app quartz shuts down properly and the app finishes when main exits, but under tomcat it will not shutdown due to quartz. To solve this I had to implement the servlet destroy() method and physically shutdown the quartzscheduler
          eg (simplified):
          Scheduler sched= (Scheduler)ctx.getCtx().getBean("quartzSchedulerFa ctory");
          sched.shutdown(false);

          This works perfectly and allows tomcat to shutdown cleanly, but shouldnt spring be able to shutdown quartz by itself in this case?
          Am I missing something or is this a bug?

          Comment


          • #6
            Originally posted by jasone View Post
            This works perfectly and allows tomcat to shutdown cleanly, but shouldnt spring be able to shutdown quartz by itself in this case?
            As far as I can see, it would be doing this already. The factory bean implements DisposableBean and this calls scheduler.shutdown().

            Comment


            • #7
              Originally posted by karldmoore View Post
              As far as I can see, it would be doing this already. The factory bean implements DisposableBean and this calls scheduler.shutdown().
              I agree it should - but it doesnt. this is my singleton(simplified):
              public class SpringAppContainer {
              private static SpringAppContainer instance;
              private ApplicationContext ctx = null;
              private SpringAppContainer() {
              super();
              }

              public static synchronized SpringAppContainer getInstance()
              {
              if (instance == null) {
              try {
              instance = new SpringAppContainer();
              instance.ctx = new ClassPathXmlApplicationContext("classpath*:au/mypackage/....../applicationContext*.xml");
              }
              catch (Exception e)
              {
              ..
              }
              }
              return instance;
              }

              public ApplicationContext getCtx() {
              return ctx;
              }
              }

              and I instantiate it in a servlet eg:
              public class MyServlet extends HttpServlet {
              private static SpringAppContainer ctx=SpringAppContainer.getInstance();
              ...

              so now spring is up doing its thing, quartz is configured etc and all is well, but I cant shutdown tomcat without explicitly shutting down the scheduler, and I've tried it on Windows, linux, and Solaris
              I tried everything from the latest version of spring and quartz to various 1.x versions of spring because according to some message threads I found, there had existed in some previous versions of spring a suspiciously similar problem that was alleged to be fixed since 1.5. I suspect spring will shutdown properly if I were to use the ContextLoaderServlet or the listener -perhaps it does something to initialise proper shutdown of spring?

              Comment


              • #8
                Have a look at "3.5.1.2.2. Shutting down the Spring IoC container gracefully in non-web applications", just above the link below.
                http://www.springframework.org/docs/...-factory-aware

                Comment


                • #9
                  I have no problem in a standalone - no web app. That ref is specifically for non-web containers - quote:

                  Note
                  This next section does not apply to web applications (in case the title of this section did not make that abundantly clear). Spring's web-based ApplicationContext implementations already have code in place to handle shutting down the Spring IoC container gracefully when the relevant web application is being shutdown.

                  Comment


                  • #10
                    but I guess if I'm not using a "real" web-based applicationcontext I should use this?

                    THanks.

                    Comment


                    • #11
                      doesnt work anyway - tried it with ConfigurableApplicationContext and registerShutdownHook() but it doesnt work. tomcat wont shutdown unless I explicitly kill quartz.

                      Comment


                      • #12
                        You could always get rid of SpringAppContainer or atleast change the way it works. Use ContextLoaderListener in the web app, explicitly create an ApplicationContext in a non-web app and then update SpringAppContainer to implement ApplicationContextAware. StringAppContainer is a questionable class anyway.

                        Comment


                        • #13
                          This thread is long dead but I found it because I had the same problem. I will post my solution for any future Googlers with the same problem. In the definition of your SchedulerFactoryBean, the destroy method DOES get called even if it is not explicitly defined in your application context. If you look at the source for SchedulerFactoryBean.destroy you will see that it does, in fact, call the shutdown() method of the scheduler. When I turn up the logging on this class I can in fact see that it is run. The problem seems to be that Quartz needs a second to shutdown cleanly. However, the waitForJobsToCompleteOnShutdown doesn't seem to help with this.

                          My solution was to write a custom ServlertContextListener and register it in the web.xml. In the contextDestroyed() method, get a reference to the Scheduler and shut it down manually, then wait for 1 second before continuing. This was the only solution that worked for me

                          public class ShutDownHook implements ServletContextListener
                          {

                          @Override
                          public void contextDestroyed(ServletContextEvent arg0)
                          {
                          try
                          {
                          // Get a reference to the Scheduler and shut it down
                          WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
                          Scheduler scheduler = (Scheduler) context.getBean("quartzSchedulerFactory");
                          scheduler.shutdown(true);

                          // Sleep for a bit so that we don't get any errors
                          Thread.sleep(1000);
                          }
                          catch (Exception e)
                          {
                          e.printStackTrace();
                          }
                          }

                          @Override
                          public void contextInitialized(ServletContextEvent arg0)
                          {
                          }

                          Comment


                          • #14
                            quartzSchedulerFactory definition

                            Hi,

                            Please tell me the definition of "quartzSchedulerFactory"
                            in

                            WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
                            Scheduler scheduler = (Scheduler) context.getBean("quartzSchedulerFactory");

                            Thx
                            masaai

                            Comment


                            • #15
                              I just ran into this same issue. Thanks for posting this as it worked. I'm using the new:

                              <task:scheduler id="taskScheduler" pool-size="10">

                              It does have a shutdown() on it but I can't use destroy-method on the bean. Your fix works for now but I'm going to look into a more spring like way of doing this. Thanks again!!

                              Comment

                              Working...
                              X