Tengo un archivo WAR desplegado en el servidor Tomcat, se llamará a una de las clases en el momento del inicio, luego el método init() programará un temporizador para que se active cada 5 horas para realizar algunas tareas .Detener el temporizador programado al cerrar tomcat
Mi init() código es el siguiente:
public void init()
{
TimerTask parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
Timer parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
Mi aplicación se ejecuta sin ningún problema, pero cuando el apagado del Tomcat mediante /etc/init.d/tomcat7 paro, entonces puedo comprobar el registro (catalina.out) tiene una entrada como esta:
SEVERE: Parece que la aplicación web [/ MyApplication] ha iniciado un hilo llamado [Timer-0] pero no ha podido detenerlo. Esto es muy probable que cree una pérdida de memoria.
entiendo que esto es causado por mí programar el temporizador, pero mi pregunta es:
- No me propuse
setDeamon
true, por lo que no debería impedir que el temporizador Tomcat desde el cierre, en lugar de dejado corriendo? - ¿Puedo, en mi aplicación, detectar que Tomcat va a estar apagado y cancelar mi temporizador?
- ¿Cuáles son las otras soluciones que puedo usar para solucionar este problema?
¡Gracias!
ACTUALIZACIÓN
he cambiado de código a la siguiente basado en alguna búsqueda y la respuesta de DaveHowes.
Timer parserTimer;
TimerTask parserTimerTask;
public void init()
{
parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
Logger logger = Logger.getRootLogger();
logger.info("DETECT TOMCAT SERVER IS GOING TO SHUT DOWN");
logger.info("CANCEL TIMER TASK AND TIMER");
otsParserTimerTask.cancel();
otsParserTimer.cancel();
logger.info("CANCELING COMPLETE");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
}
Ahora mi nueva pregunta:
- cancelo TimerTask primero y luego temporizador, es esto correcto?
- ¿Hay alguna otra cosa que deba hacer?
¡Gracias!
ACTUALIZACIÓN
No funciona. Puse una declaración de registro en el método contextDestroyed(), después de cerrar Tomcat, el archivo de registro solo tiene lo siguiente:
PowderGodAppWebService -> [07 Feb 2012 04:09:46 PM] INFO (PowderGodAppWebService.java:45) :: DETECTAR servidor Tomcat VA A APAGAR PowderGodAppWebService -> [07 Feb 2012 04:09:46 PM] INFO (PowderGodAppWebService.java:46) :: CANCELAR Task Timer y el temporizador
con cancelación COMPLETA es no ahí.
También verifiqué los procesos que se están ejecutando (no soy un experto en Linux, así que solo uso el Monitor de actividad de Mac).
- Asegúrese de que hay un proceso de Java se ejecuta
- iniciar Tomcat, tenga en cuenta el PID de ese proceso java
- Parar Tomcat
- Encontrado el proceso Tomcat se ha ido
- iniciar Tomcat, tenga en cuenta el PID ese proceso java
- instalar mi archivo de la guerra
- Muestra el proceso, ver [Timer-0] hilo no es
- Shutdown Tomcat
- encontrado que el procedimiento está todavía allí
- Muestra el proceso
- Ver [Timer-0] es todavía allí
FIJO
he cambiado de código para parserTimer = new Timer(true);
para que mi temporizador se ejecute como un hilo daemon porque se llama al contextDestroyed()
después de que Tomcat se apaga.
"Todos los servlets y filtros se habrán destruido antes de que se notifique a ServletContextListeners sobre la destrucción del contexto".
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
esos Cancela no deben estar en contextDestroyed()? – DaveH
Sí ... creo que es hora de ir a la cama, ¡gracias por señalar! –
TimerTask # cancel no interrumpirá la tarea si se está ejecutando actualmente; solo se asegurará de que nunca vuelva a ejecutarse, pero aparte de eso, yo diría que con eso estaría bien – DaveH