2010-04-28 21 views
14

Durante lo sviluppo di un programma di pianificazione basato primavera in un contenitore di Tomcat, ho sempre ottenere questo LogOutput a undeploy webapp o l'arresto del server:Primavera errore Shutdown Scheduler

Apr 28, 2010 4:21:33 PM org.apache.catalina.core.StandardService stop 
INFO: Stopping service Catalina 
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] but has failed to stop it. This is very likely to create a memory leak. 
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2] but has failed to stop it. This is very likely to create a memory leak. 
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3] but has failed to stop it. This is very likely to create a memory leak. 
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] but has failed to stop it. This is very likely to create a memory leak. 
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-5] but has failed to stop it. This is very likely to create a memory leak. 
. 
. 
.  
SEVERE: A web application created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [Prototype beans currently in creation]) and a value of type [null] (value [null]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed. 
Apr 28, 2010 4:21:34 PM org.apache.coyote.http11.Http11Protocol destroy 
INFO: Stopping Coyote HTTP/1.1 on http-8606 

Come posso risolvere questo problema?

ringraziamento stevedbrown

Ho aggiunto questa ascoltatore al mio webapp

public class ShutDownHook implements ServletContextListener { 
    @Override 
    public void contextDestroyed(ServletContextEvent arg0) { 
     BeanFactory bf = (BeanFactory) ContextLoader.getCurrentWebApplicationContext(); 
     if (bf instanceof ConfigurableApplicationContext) { 
      ((ConfigurableApplicationContext)bf).close(); 
     } 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent arg0) { 
    } 
} 

e il mio web.xml

<listener> 
    <listener-class>pkg.utility.spring.ShutDownHook</listener-class> 
</listener> 

ma l'errore è ancora lì.

primavera config:

<bean id="run" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
    <property name="concurrent" value="false" /> 
    <property name="targetObject" ref="scheduler" /> 
    <property name="targetMethod" value="task" /> 
</bean> 

<bean id="cronTrg" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
    <property name="jobDetail" ref="run" /> 
    <property name="cronExpression" value="0/5 * * * * ?" /> 
</bean> 

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" destroy-method="destroy"> 
    <property name="triggers"> 
     <list> 
      <ref bean="cronTrg" /> 
     </list> 
    </property> 
</bean> 
+0

hey Alex, hai qualche soluzione per questo problema? – Joe

risposta

2

è necessario aggiungere un gancio di arresto - vedi Registering a shutdown hook in Spring 2.5.

Nel tuo caso, probabilmente dovresti aggiungere un listener di contesto alla tua webapp che esegue questa operazione (voce web.xml per la classe di implementazione listener +).

Utilizzare vicino, è più semplice.

+0

Aggiungo l'ascoltatore ma non succede niente. – Alex

+1

Si desidera ((ConfigurableApplicationContext) bf) .close() ;, not ((ConfigurableApplicationContext) bf) .registerShutdownHook(); a meno che non si voglia effettivamente registrare il gancio di arresto con il proprio runtime [buono per junit] (Runtime.getRuntime().addShutdownHook (new Thread() { public void run() { se (CTX instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext) CTX) .close();} } }); ) – stevedbrown

+0

Sono cieco quale oggetto devo chiudere, ho aggiunto la configurazione a molla e ho modificato la mia classe di ascoltatori. – Alex

2

Ecco la mia soluzione poiché nessuno di quelli che ho trovato online funzionava. Questo è specifico per spegnere lo scheduler al quarzo con molla & Tomcat

La mia spiegazione è qui: http://forum.springsource.org/showthread.php?34672-Quartz-doesn-t-shutdown&p=370060#post370060

In sostanza ciò che il problema sembrava essere è che il quarzo non ha abbastanza tempo per lo spegnimento in modo pulito e l'argomento waitForJobsToCompleteOnShutdown doesn sembra aiutare. Quindi ho implementato un listener di spegnimento personalizzato nella webapp, ottenere un riferimento allo scheduler e spegnerlo manualmente. E poi attendi 1 secondo prima di procedere.

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) 
    { 
    } 
5

Imho questo è un problema dello scheduler del quarzo. Ho presentato un errore https://jira.terracotta.org/jira/browse/QTZ-192. Come soluzione alternativa, la soluzione sleep() suggerita da Colin Peters funziona per me. Per non innescare l'arresto per due volte si potrebbe anche aggiungere il sonno a SchedulerFactoryBean di primavera:

import org.quartz.SchedulerException; 
import org.springframework.scheduling.quartz.SchedulerFactoryBean; 

public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean{ 

    @Override 
    public void destroy() throws SchedulerException { 
    super.destroy(); 
    // TODO: Ugly workaround for https://jira.terracotta.org/jira/browse/QTZ-192 
    try { 
     Thread.sleep(1000); 
    } catch(InterruptedException e) { 
     throw new RuntimeException(e); 
    } 
    } 
} 
+2

Il problema del quarzo è stato risolto con Quartz 2.1. Sfortunatamente, Spring 3.1 è basato su Quartz 1.8 e un aggiornamento a 2.0 è considerato per Spring 3.2 al più presto. Fonte: https://jira.springsource.org/browse/SPR-7987 – StefanR

+1

In realtà Spring 3.1 supporta quartz 2.x http://www.infoq.com/news/2011/10/spring-3.1-rc1-release – bmurmistro

+0

Ho aggiornato a SpringFramework 4.1.6.RELEASE e Quartz 2.1.7 e ho dovuto ancora fare questo lavoro ... – TungstenX