Search code examples
timerejbschedulingjava-ee-8

Why should we use @Startup for timer service in EJB?


I had a service as:

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class JobTest {

    @Resource
    private TimerService timerService;

    @PostConstruct
    public void init() {
        timerService.createTimer(0,1000, "Every second timer with no delay");
    }

    @Timeout
    public void execute() {
        System.out.println("execute your job here");
    }

}

However, the job wasn't executed. But when added @Startup to the service, the code run as expected. Could you explain why we needed @Startup to use timerService resource.


Solution

  • EJB container does not create instances of managed beans unless those are being looked up, injected, or annotated with @Startup. The method annotated with @PostConstruct is never called for the EJB in the question, therefore the timer is never created, therefore no callbacks occur.

    If you have to use programmatically created timers (due to delay value coming from the configuration), you need to force the eager initialization - by either annotating the bean with the @Startup or injecting it into another @Startup bean.

    Another option is to use automatically created timers by annotating a method with the @Schedule annotation, though the timer configuration is hardcoded in this case.