Donnerstag, 13. Oktober 2011

"reschedule-failed-timer" in GlassFish 3.1

In Stateless Session Beans, Singleton Beans und Message Driven Beans kann der EJB-Timer-Service genutzt werden. Ab EJB 3.1 ist es dabei sehr einfach geworden, wiederkehrende Intervall-Timer mit der @Schedule-Annotation zu definieren (eine programmatische Definition ist natürlich weiterhin möglich).

Wenn ein periodischer Timer eine Exception wirft, wird GlassFish sofort noch zweimal versuchen, die Timer-Methode auszuführen. Werden auch diese Aufrufe mit Exceptions abgebrochen, stoppt GlassFish den Timer komplett, d.h. auch nach Ablauf des nächsten Intervall-Zeitraums erfolgt kein Aufruf mehr! Ich bin mir nicht sicher, ob dieses Verhalten von der EJB-Spezifikation gedeckt ist – intuitiv dürfte man aber vermutlich erwarten, dass Intervall-Timer zuverlässig ausgeführt werden.

Seit GlassFish 3.1 gibt es eine Server-Property "reschedule-failed-timer", mit der dieses Verhalten konfiguriert werden kann. Über das Konfigurationsprogramm asadmin kann man mit

asadmin set configs.config.server-config.ejb-container.ejb-timer-service.property.reschedule-failed-timer=true

einstellen, dass auch per Exception abgebrochene Timer nach Ablauf des nächsten Intervall-Zeitraums wieder aufgerufen werden. Durch den Aufruf wird in domain.xml folgender Abschnitt eingetragen:
<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>
Ohne das Setzen der Property bleibt ansonsten nur, den gesamten Timer-Methoden-Rumpf in try { ... } catch (Exception ...) einzufassen, damit garantiert keine Exception den Timer verlässt.