title: How to stop threads when undeploying a Java EE application?
body: <p>I undeploy my Java EE app that uses an asynchronous logger that logs in its own thread from the Drools rules engine. I use it to log decisions the rules engine makes but I cannot let it have impact on the throughput, therefore it must run in its own thread.</p>
  
  <p>I get pages of Exceptions when I undeploy it indicating that it was not closed properly. That might be true since the logger is just a thread like this:</p>
  
  <pre><code>while(true){
    log(something)  
    sleep(someTime);
  }
  </code></pre>
  
  <p>It may not have time to react properly when it is sleeping and the undeploy starts. Unfortunately I cannot get the thread itself from the logger, so I cannot join on it in a @PreDestroy method. How can I avoid the Exceptions when I undeploy?</p>
  
  <p>the Excpetions:</p>
  
  <pre><code>    [#|2010-07-19T15:50:10.123+0200|WARNING|sun-appserver2.1|javax.enterprise.system.core.classloading|_ThreadID=24;_ThreadName=Thread-258;_RequestID=22a7d379-0813-4248-9095-3fba7f4cb95a;|LDR5206: EJBClassLoader EJBClassLoader : 
  doneCalled = true
  doneSnapshot = EJBClassLoader.done() called ON EJBClassLoader : 
  urlSet = [URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/jaxp-api-1.3.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/mvel2-2.0.10.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/activation-1.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/stax-1.2.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/jms-1.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-lang-2.4.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/joda-time-1.6.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/drools-compiler-5.0.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-email-1.2.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-beanutils-core-1.8.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/Mailforwarder-pojo-1.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/xml-apis-1.0.b2.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-logging-1.1.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/janino-2.5.15.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-digester-1.8.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/drools-api-5.0.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-net-2.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-lang-2.5.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/core-3.4.2.v_883_R34x.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/xpp3_min-1.1.4c.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/stax-api-1.0.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-configuration-1.6.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-collections-3.2.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/xstream-1.3.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/commons-beanutils-1.7.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/core-pojo-1.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/core-common-1.0.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/xml-writer-0.2.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/antlr-runtime-3.1.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/mail-1.4.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/activation.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/lib/drools-core-5.0.1.jar, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/applications/j2ee-apps/mailforwarder/Mailforwarder-ejbjar-1.0_jar/, URLEntry : file:/home/arne/env/runtime/glassfish/domains/domain1/generated/ejb/j2ee-apps/mailforwarder/]
  doneCalled = false 
   Parent -&gt; EJBClassLoader : 
  urlSet = []
  doneCalled = false 
   Parent -&gt; java.net.URLClassLoader@898540
  
  
   AT Mon Jul 19 15:47:21 CEST 2010 
   BY :com.sun.enterprise.loader.EJBClassLoader.printStackTraceToString(EJBClassLoader.java:813)
  com.sun.enterprise.loader.EJBClassLoader.done(EJBClassLoader.java:173)
  com.sun.enterprise.server.AbstractLoader.done(AbstractLoader.java:355)
  com.sun.enterprise.server.ApplicationLoader.unload(ApplicationLoader.java:268)
  com.sun.enterprise.server.TomcatApplicationLoader.unload(TomcatApplicationLoader.java:218)
  com.sun.enterprise.server.ExtendedApplicationLoader.unload(ExtendedApplicationLoader.java:263)
  com.sun.enterprise.server.ApplicationManager.applicationUndeployed(ApplicationManager.java:525)
  com.sun.enterprise.server.ApplicationManager.applicationUndeployed(ApplicationManager.java:703)
  com.sun.enterprise.admin.event.AdminEventMulticaster.invokeApplicationDeployEventListener(AdminEventMulticaster.java:961)
  com.sun.enterprise.admin.event.AdminEventMulticaster.handleApplicationDeployEvent(AdminEventMulticaster.java:943)
  com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(AdminEventMulticaster.java:467)
  com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(AdminEventMulticaster.java:182)
  com.sun.enterprise.admin.server.core.DeploymentNotificationHelper.multicastEvent(DeploymentNotificationHelper.java:308)
  com.sun.enterprise.deployment.phasing.DeploymentServiceUtils.multicastEvent(DeploymentServiceUtils.java:231)
  com.sun.enterprise.deployment.phasing.ServerDeploymentTarget.sendStopEvent(ServerDeploymentTarget.java:332)
  com.sun.enterprise.deployment.phasing.ApplicationStopPhase.runPhase(ApplicationStopPhase.java:136)
  com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108)
  com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:966)
  com.sun.enterprise.deployment.phasing.PEDeploymentService.undeploy(PEDeploymentService.java:333)
  com.sun.enterprise.deployment.phasing.PEDeploymentService.undeploy(PEDeploymentService.java:308)
  com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.undeploy(ApplicationsConfigMBean.java:667)
  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  java.lang.reflect.Method.invoke(Method.java:597)
  com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:390)
  com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:373)
  com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:477)
  com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
  com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
  sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
  sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  java.lang.reflect.Method.invoke(Method.java:597)
  com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90)
  $Proxy1.invoke(Unknown Source)
  com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304)
  com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:170)
  com.sun.enterprise.deployment.autodeploy.AutoDeployer.invokeUndeploymentService(AutoDeployer.java:903)
  com.sun.enterprise.deployment.autodeploy.AutoDeployer.undeployJavaEEArchive(AutoDeployer.java:399)
  com.sun.enterprise.deployment.autodeploy.AutoDeployer.undeployApplication(AutoDeployer.java:381)
  com.sun.enterprise.deployment.autodeploy.AutoDeployer.undeployAll(AutoDeployer.java:315)
  com.sun.enterprise.deployment.autodeploy.AutoDeployControllerImpl$AutoDeployTask.run(AutoDeployControllerImpl.java:375)
  java.util.TimerThread.mainLoop(Timer.java:512)
  java.util.TimerThread.run(Timer.java:462)
   Parent -&gt; EJBClassLoader : 
  urlSet = []
  doneCalled = false 
   Parent -&gt; java.net.URLClassLoader@898540
  
   was requested to find resource META-INF/services/javax.xml.datatype.DatatypeFactory after done was invoked from the following stack trace
  java.lang.Throwable
          at com.sun.enterprise.loader.EJBClassLoader.findResource(EJBClassLoader.java:459)
          at java.lang.ClassLoader.getResource(ClassLoader.java:978)
          at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1168)
          at com.sun.enterprise.loader.EJBClassLoader.getResourceAsStream(EJBClassLoader.java:796)
          at javax.xml.datatype.SecuritySupport$4.run(SecuritySupport.java:92)
          at java.security.AccessController.doPrivileged(Native Method)
          at javax.xml.datatype.SecuritySupport.getResourceAsStream(SecuritySupport.java:85)
          at javax.xml.datatype.FactoryFinder.findJarServiceProvider(FactoryFinder.java:250)
          at javax.xml.datatype.FactoryFinder.find(FactoryFinder.java:223)
          at javax.xml.datatype.DatatypeFactory.newInstance(DatatypeFactory.java:131)
          at com.thoughtworks.xstream.converters.extended.DurationConverter.&lt;init&gt;(DurationConverter.java:33)
          at sun.reflect.GeneratedConstructorAccessor70.newInstance(Unknown Source)
          at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
          at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
          at com.thoughtworks.xstream.XStream.dynamicallyRegisterConverter(XStream.java:725)
          at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:696)
          at com.thoughtworks.xstream.XStream.&lt;init&gt;(XStream.java:445)
          at com.thoughtworks.xstream.XStream.&lt;init&gt;(XStream.java:385)
          at com.thoughtworks.xstream.XStream.&lt;init&gt;(XStream.java:323)
          at org.drools.audit.WorkingMemoryFileLogger.writeToDisk(WorkingMemoryFileLogger.java:120)
          at org.drools.audit.ThreadedWorkingMemoryFileLogger.writeToDisk(ThreadedWorkingMemoryFileLogger.java:38)
          at org.drools.audit.ThreadedWorkingMemoryFileLogger$Writer.run(ThreadedWorkingMemoryFileLogger.java:50)
          at java.lang.Thread.run(Thread.java:619)
  |#]
  </code></pre>
  
  <hr>
  
  <p>I did not made clear enough what I wanted in this question, sorry for that. I asked a new <a href="https://stackoverflow.com/questions/3316300/how-do-i-know-when-a-jee-app-is-undeployed">question here</a></p>