2010-07-22 7 views
7

Annullo la mia app Java EE che utilizza un logger asincrono che registra il proprio thread dal motore delle regole di Drools. Lo uso per registrare le decisioni che il motore delle regole fa, ma non posso lasciare che abbia un impatto sulla velocità effettiva, quindi deve essere eseguito nella sua stessa thread.Come interrompere i thread quando si disimpegna un'applicazione Java EE?

Ottengo pagine di Eccezioni quando lo annullo per indicare che non è stato chiuso correttamente. Questo potrebbe essere vero in quanto il registratore è solo un filo come questo:

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

Esso non può avere il tempo di reagire correttamente quando si sta dormendo e inizia undeploy. Sfortunatamente non riesco a ottenere il thread stesso dal logger, quindi non posso unirmi su di esso in un metodo @PreDestroy. Come posso evitare le eccezioni quando annullamento della distribuzione?

le 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) 
|#] 

non ho fatto abbastanza chiaro quello che volevo in questa domanda, mi spiace per quello. Ho chiesto un nuovo question here

risposta

12

Piuttosto usare ScheduledExecutorService#scheduleAtFixedRate() anziché il vecchio stile Thread#sleep(). Puoi utilizzare ServletContextListener per eseguirlo all'avvio di webapp e interromperlo sull'arresto di 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. 
    } 

} 

Dove Task può apparire come segue:

public class Task implements Runnable { 

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

} 

Se l'ambiente non supporta Servlet 3.0 @WebListener, quindi registrarlo come segue in web.xml per farlo funzionare:

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

Grazie per la risposta. Non ho implementato il logger da solo, ma viene fornito con il motore delle regole Drools. Pertanto non posso modificare l'implementazione. Né posso ottenere il thread che usa per fare il logging. Non c'è getter per quello. Ho appena esaminato la fonte delle lezioni di drools e ho visto l'implementazione con la funzione sleep. Quindi la mia domanda rimane: esiste un modo per sapere quando l'app non è distribuita? finallize arriva troppo tardi, @PreDestroy viene chiamato durante il normale funzionamento dal contenitore. In che modo l'app può sapere quando è disattivata? – Arne

+0

Per chiarire: l'eccezione dice: "Il flusso di input è stato finalizzato o forzato chiuso senza essere chiuso esplicitamente". La mia domanda è: come posso chiuderla quando annullamento della distribuzione? la chiusura viene eseguita con il metodo close(), ma quando? – Arne