title: What is the proper way to shutdown threads when tomcat closes?
body: <p>I am trying to shutdown threads when Tomcat is being shutdown.<br>
  Specifically I am trying to shutdown log4j watchdog (for filechanges) and also I am trying to shutdown an executor which uses a class in my web app.<br>
  On shutdown I see exceptions in Catalina.out.<br>
  For Log4J I see:  </p>
  
  <blockquote>
    <p>INFO: Illegal access: this web application instance has been stopped<br>
    already.  Could not load org.apache.log4j.helpers.NullEnumeration.<br>
    The eventual following stack trace is caused by an error thrown for<br>
    debugging purposes as well as to attempt to terminate the thread which<br>
    caused the illegal access, and has no functional impact. Throwable<br>
    occurred: java.lang.IllegalStateException<br>
            at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1587)<br>
            at   org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1546)<br>
            at org.apache.log4j.Category.getAllAppenders(Category.java:413)<br>
            at org.apache.log4j.Category.closeNestedAppenders(Category.java:226)<br>
            at org.apache.log4j.Hierarchy.shutdown(Hierarchy.java:467)<br>
            at org.apache.log4j.LogManager.shutdown(LogManager.java:267)<br>
            at com.listeners.myListener$1.run(myListener.java:232)<br>
    Exception in thread "Thread-14" java.lang.NoClassDefFoundError:<br>
    org.apache.log4j.helpers.NullEnumeration<br>
            at org.apache.log4j.Category.getAllAppenders(Category.java:413)<br>
            at org.apache.log4j.Category.closeNestedAppenders(Category.java:226)<br>
            at org.apache.log4j.Hierarchy.shutdown(Hierarchy.java:467)<br>
            at org.apache.log4j.LogManager.shutdown(LogManager.java:267)  </p>
  </blockquote>
  
  <p>And for the executor part:  </p>
  
  <blockquote>
    <p>INFO: Illegal access: this web application instance has been stopped<br>
    already.  Could not load com.my.class.SomeClass.  The eventual<br>
    following stack trace is caused by an error thrown for debugging<br>
    purposes as well as to attempt to terminate the thread which caused<br>
    the illegal access, and has no functional impact. Throwable occurred:<br>
    java.lang.IllegalStateException<br>
            at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1587)<br>
            at   org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1546)<br>
            at 
    Exception in thread "Thread-13" java.lang.NoClassDefFoundError:<br>
    com.my.class.SomeClass  </p>
  </blockquote>
  
  <p>What I am doing is in <code>ServletContextListener</code> on <code>contextDestroyed</code> I have added shutdown hooks as follows:  </p>
  
  <pre><code>public void contextDestroyed(ServletContextEvent arg0) {  
  
           Runtime.getRuntime().addShutdownHook(new Thread(){  
              @Override  
              public void run(){  
                  LogManager.shutdown();                  
              }  
           });  
  
      } 
  
  
  
  
  
   public void contextDestroyed(ServletContextEvent arg0) {  
  
          Runtime.getRuntime().addShutdownHook(new Thread(){  
              @Override  
              public void run(){  
                  SomeClass.updater.shutdown();  
              }  
          });  
  
      }  
  </code></pre>
  
  <p>What am I doing wrong here? Why do I get exceptions?  </p>
  
  <p><strong>UPDATE:</strong><br>
  <code>SomeClass.updater</code> is a <code>public static ScheduledExecutorService</code>.<br>
  <code>LogManager</code> is <code>org.apache.log4j.LogManager</code>  </p>
  
  <p><strong>UPDATE2:</strong><br>
  After following the answer from BGR I do directly </p>
  
  <pre><code>public void contextDestroyed(ServletContextEvent arg0) {  
  
              SomeClass.updater.shutdown();  
  
          }  
  </code></pre>
  
  <p>and  </p>
  
  <pre><code>public void contextDestroyed(ServletContextEvent arg0) {  
  
                  LogManager.shutdown();                  
  
          } 
  </code></pre>
  
  <p>I don't get exception from Log4j but I get the following exception for <code>SomeClass.updater</code> which is a <code>public static ScheduledExecutorService</code>:   </p>
  
  <blockquote>
    <p>INFO: Illegal access: this web application instance has been stopped<br>
    already.  Could not load java.util.concurrent.ExecutorService.  The<br>
    eventual following stack trace is caused by an error thrown for<br>
    debugging purposes as well as to attempt to terminate the thread which<br>
    caused the illegal access, and has no functional impact. Throwable<br>
    occurred: java.lang.IllegalStateException<br>
            at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1587)<br>
            at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1546)  </p>
  </blockquote>
  
  <p>Why? Are the classes already been garbage collected?</p>