2010-07-22 11 views
7

Je annule le déploiement de mon application Java EE qui utilise un enregistreur asynchrone qui enregistre son propre thread à partir du moteur de règles Drools. Je l'utilise pour consigner les décisions prises par le moteur de règles, mais je ne peux pas le laisser avoir un impact sur le débit, il doit donc fonctionner dans son propre thread.Comment arrêter les threads lors du non-déploiement d'une application Java EE?

Je reçois des pages d'exceptions lorsque je l'annule en indiquant qu'il n'a pas été fermé correctement. Cela pourrait être vrai que l'enregistreur est juste un fil comme celui-ci:

while(true){ 
    log(something) 
    sleep(someTime); 
} 

Il ne peut pas avoir le temps de réagir correctement quand il dort et le début undeploy. Malheureusement, je ne peux pas obtenir le thread lui-même de l'enregistreur, donc je ne peux pas le rejoindre dans une méthode @PreDestroy. Comment puis-je éviter les exceptions lorsque je ne suis pas déployé?

les Excpetions:

[#|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 -> EJBClassLoader : 
urlSet = [] 
doneCalled = false 
Parent -> [email protected] 


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 -> EJBClassLoader : 
urlSet = [] 
doneCalled = false 
Parent -> [email protected] 

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.<init>(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.<init>(XStream.java:445) 
     at com.thoughtworks.xstream.XStream.<init>(XStream.java:385) 
     at com.thoughtworks.xstream.XStream.<init>(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) 
|#] 

Je ne l'ai pas fait assez clairement ce que je voulais dans cette question, désolé. J'ai demandé à un nouveau question here

Répondre

12

Plutôt utiliser ScheduledExecutorService#scheduleAtFixedRate() au lieu de l'ancien Thread#sleep(). Vous pouvez utiliser ServletContextListener pour l'exécuter au démarrage de webapp et l'arrêter lors de l'arrêt de webapp.

@WebListener 
public class Config implements ServletContextListener { 

    private ScheduledExecutorService scheduler; 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     scheduler = Executors.newSingleThreadScheduledExecutor(); 
     scheduler.scheduleAtFixedRate(new Task(), 0, 1, TimeUnit.MINUTES); // Schedule to run every minute. 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
     scheduler.shutdown(); // Important! This stops the thread. 
    } 

} 

Task peut ressembler à ceci:

public class Task implements Runnable { 

    @Override 
    public void run() { 
     log(something); 
    } 

} 

Si votre environnement ne prend pas en charge Servlet 3.0 @WebListener, puis l'enregistrer comme suit web.xml pour l'obtenir à exécuter:

<listener> 
    <listener-class>com.example.Config</listener-class> 
</listener> 
+0

Merci pour votre réponse. Je n'ai pas implémenté l'enregistreur moi-même, il est fourni avec le moteur de règles Drools. Par conséquent, je ne peux pas changer la mise en œuvre. Je ne peux pas non plus obtenir le thread qu'il utilise pour faire la journalisation. Il n'y a pas de getter pour ça. J'ai juste regardé dans la source des classes drools et j'ai vu l'implémentation avec la fonction sleep. Donc, ma question demeure: est-il possible de savoir quand l'application n'est pas déployée? Finallize arrive trop tard, @PreDestroy est appelé pendant le fonctionnement normal du conteneur. Comment l'application peut-elle savoir quand elle n'est pas déployée? – Arne

+0

Pour clarifier: l'exception dit: "Flux d'entrée a été finalisé ou forcé fermé sans être explicitement fermé". Ma question est: comment puis-je la fermer quand je ne suis pas déployé? la fermeture est faite avec la méthode close(), mais quand? – Arne