I have some issues with my EJB 3 timer where it is launched more than once. Rather than configuring the timer in an annotation, I use programmatic configuration, as explain in many blogs. Here's my code:
@Singleton
@Startup
public class AutoAssignTask extends AbstractDirectoryMonitor {
@Resource
private TimerService timer;
@Inject
@PropertyResource(name = "timer.hour", resource = "/DL4/app.conf")
private String hour;
@Inject
@PropertyResource(name = "timer.minute", resource = "/DL4/app.conf")
private String minute;
@Inject
@PropertyResource(name = "timer.second", resource = "/DL4/app.conf")
private String second;
@EJB
private AutoAssignService autoAssignService;
@PostConstruct
public void init() {
// initializing with an expression.
this.initSchedule();
}
protected void initSchedule() {
ScheduleExpression exp = new ScheduleExpression();
if (!StringUtils.isEmpty(this.getHour())) {
exp.hour(this.getHour());
}
if (!StringUtils.isEmpty(this.getMinute())) {
exp.minute(this.getMinute());
}
if (!StringUtils.isEmpty(this.getSecond())) {
exp.second(this.getSecond());
}
this.getTimer().createCalendarTimer(exp);
}
@Timeout
public void process() {
// do something
AutoAssignTask.LOG.info("starting job.");
}
Now let's say I configure the timer for every minute, when I look at my logs I get twice the "starting job" log, proving it starts the job twice.
Any ideas on what is wrong?
A few thoughts:
initSchedule()
method. The problem could be in the ScheduleExpression
.AutoAssignTask
is further sub-classed the @PostConstruct
of AutoAssignTask
will still be called. More simply put, the @PostConstruct
method of an EJB's super classes are also invoked -- the oldest parent first.For number 2 and 3, a simple static AtomicInteger and log statement would work:
public class AutoAssignTask extends AbstractDirectoryMonitor {
private static final AtomicInteger instances = new AtomicInteger();
@PostConstruct
public void init() {
System.out.println("AutoAssignTask instance "+instances.incrementAndGet());
//....
}
}