I have a method annotated with @Schedule that is called by the container once in a while.
@Schedule(second = \"*/5\", minute = \"*\", hour = \"*\", persisten
The current Glassfish up to version 4 expunges a timer if during the execution of the timeout callback method an application exception occurs.
The application exception causes a rollback of the current transaction. In such a situation Glassfish retries the error free execution of the timeout callback method once again. If a rollback again occurs Glassfish expunges the timer.
I filed an issue in the Glassfish issue tracker not to expunge the timer in case of an excpetion. Glassfish seems to be the only application server who expunges a timer in case of an application exception. See glassfish #20749: Glassfish expunges timer even if callback method keeps its contract for more details. May you would like to vote for my issue.
I also filed an issue on the EJB specification to clarify how the EJB container should behave in such situations. See ejb-spec #111: Please clearify the behaviour of an container if an application exception is thrown during the execution of a timer callback method for more details.
I'd use a different approach.
Instead of throwing an exception directly from the scheduled method, try to introduce a level of indirection as in:
...
@Inject RealWorkHere realImplementation;
@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void myTimerMethod(){
try{
realImplementation.myTimerMethodImpl()
}catch (Exception x){
// hopefully log it somewhere
}
}
...
where RealWorkHere
is the bean with the actual implementation as in:
@Stateless
public class RealWorkHere{
@TransactionAttribute(REQUIRES_NEW)
public void myTimerMethod() throws Exception {
}
}
This comes with the benefit of: