java glassfish java-ee-6 ejb-3.1

java - Evitar que el temporizador de purgado en glassfish



java-ee-6 ejb-3.1 (2)

Tengo un método anotado con @Schedule que el contenedor llama de vez en cuando.

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false) public void myTimerMethod() throws Exception { ... }

El problema está en ciertas condiciones. Quiero que este método arroje una excepción para hacer que la transacción en curso se restablezca. ¡Pero si hago esto más de dos veces el temporizador será eliminado y ya no se llamará más!

INFO: EJB5119:Expunging timer [''68@@1359143163781@@server@@domain1'' ''TimedObject = MyBean'' ''Application = My-War'' ''BEING_DELIVERED'' ''PERIODIC'' ''Container ID = 89072805830524936'' ''Fri Jan 25 21:49:30 CET 2013'' ''0'' ''*/5 # * # * # * # * # * # * # null # null # null # true # myTimerMethod # 0'' ] after [2] failed deliveries

Sé que puedo configurar la reprogramación del temporizador en domain.xml usando

<domains> ... <configs> <config> ... <ejb-container session-store="${com.sun.aas.instanceRoot}/session-store"> <ejb-timer-service> <property name="reschedule-failed-timer" value="true"></property> </ejb-timer-service> </ejb-container> ... </config> </configs> ... </domains>

Pero mi pregunta es, ¿puedo tener esta configuración configurada cuando despliegue mi aplicación?

No lo encuentro en

glassfish-resources.xml glassfish-ejb-jar.xml glassfish-web.xml

¿Hay alguna manera de hacerlo programáticamente tal vez?

(Mi razonamiento detrás de poner una configuración de servidor como ésta en los archivos de configuración en lugar de configurar el servidor es que mi aplicación debería poder instalarse directamente en una instalación nueva de glassfish)


El Glassfish actual hasta la versión 4 vence un temporizador si durante la ejecución del método de devolución de llamada de tiempo de espera se produce una excepción de la aplicación .

La excepción de la aplicación provoca una reversión de la transacción actual. En tal situación, Glassfish vuelve a intentar la ejecución sin errores del método de devolución de llamada de tiempo de espera una vez más. Si vuelve a producirse una reversión, Glassfish elimina el temporizador.

Presenté un problema en el rastreador de problemas de Glassfish para no eliminar el temporizador en caso de un fallo. Glassfish parece ser el único servidor de aplicaciones que vence un temporizador en caso de una excepción de la aplicación. Consulte glassfish # 20749: El temporizador de Glassfish se borra incluso si el método de devolución de llamada mantiene su contrato para obtener más detalles. Quisiera votar por mi tema.

También presenté un problema en la especificación EJB para aclarar cómo debería comportarse el contenedor EJB en tales situaciones. Consulte ejb-spec # 111: borre el comportamiento de un contenedor si se lanza una excepción de aplicación durante la ejecución de un método de devolución de llamada del temporizador para obtener más detalles.


Yo usaría un enfoque diferente.

En lugar de lanzar una excepción directamente desde el método programado, intente introducir un nivel de direccionamiento indirecto como en:

... @Inject RealWorkHere realImplementation; @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false) public void myTimerMethod(){ try{ realImplementation.myTimerMethodImpl() }catch (Exception x){ // hopefully log it somewhere } } ...

donde RealWorkHere es el bean con la implementación real como en:

@Stateless public class RealWorkHere{ @TransactionAttribute(REQUIRES_NEW) public void myTimerMethod() throws Exception { } }

Esto viene con el beneficio de:

  • No lanzar una excepción en una transacción iniciada por el contenedor (evitando así la eliminación)
  • Mejor registro de la excepción.
  • Clara demarcación de la transacción comercial ''real''

Ver también