Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE 7: Get @Schedule date when is set to persistent = true

In my Java EE 7 application I have created a persistent Schedule task that runs every hour. I have used @Schedule annotation.

When this job is called I want to perform some actions on events that have happened from the last hour until NOW. To obtain NOW I use "new Date()".

This @Schedule has the default persistent attribute to "true", which is great because if the server stops during hours I want to perform these tasks when it restarts.

The problem is that, if the server has been stopped during 5 hours, the job will be launched 5 times, but in all of the executions "new Date()" will be executed, and the result will be the same.

Is there any way to retrieve the date when the @Schedule job should have been launched???

like image 644
marcoslop Avatar asked Sep 29 '22 20:09

marcoslop


2 Answers

Is there any way to retrieve the date when the @Schedule job should have been launched???

I think the answer is no, there isn't.

The specification defines three interfaces that must be implemented by the Container. These interface are: TimerService, Timer and TimerHandle. As you can see, no one of them (specially Timer) exposes the method that you need. Therefore, a Java EE compliant server is not forced to implement this behavior.

Probably you should implement by yourself a solution that provides this requirement. For example, you could store the timestamp when the last callback method was executed and use this timestamp for determining the period of time (instead of subtract 1 hour to the current date)

...if the server has been stopped during 5 hours, the job will be launched 5 times...

Note that you cannot rely on this

18.4.3 Timer Expiration and Timeout Callback Method ...Any interval persistent timers or schedule based persistent timers that have expired during the intervening time must cause the corresponding timeout callback method to be invoked at least once upon restart.

like image 139
Gabriel Aramburu Avatar answered Oct 17 '22 16:10

Gabriel Aramburu


You can reconstruct the time your timer should be actually run by using javax.ejb.Timer:

@Timeout
public void timeout(Timer timer) {
    // get next time
    Date nextTime = timer.getNextTimeout();
    // substract 1 hour
    Calendar c = Calendar.getInstance();
    c.setTime(timer.getNextTimeout());
    c.add(Calendar.HOUR_OF_DAY, -1);
    Date actualTimerDate = c.getTime();
}
like image 1
Magic Wand Avatar answered Oct 17 '22 17:10

Magic Wand