Can a startup singleton bean delay a J2EE container initialization?
Asked Answered
C

1

1

According to the Java EE 6 Tutorial:

The EJB container is responsible for determining when to initialize a singleton session bean instance unless the singleton session bean implementation class is annotated with the javax.ejb.Startup annotation. In this case, sometimes called eager initialization, the EJB container must initialize the singleton session bean upon application startup. The singleton session bean is initialized before the EJB container delivers client requests to any enterprise beans in the application.

My RESTEasy application served by Thorntail doesn't use any EJB, but it uses @Startup, @Singleton and @PostConstruct annotations to run a long database update task during the initialization of the application server. It is something like this:

@Startup
@Singleton
public class StartupTask {

  @PostConstruct
  void init {
    // database update task
  }
}

Will my application be able to process HTTP requests before this task completes?

My question is similar to this one.

Coco answered 28/4, 2019 at 19:54 Comment(3)
Your @Startup @Singleton StartupTask is most definitely an EJB, so it is subject to the conditions that you have quoted above. You can circumvent the delay by moving the "database update task" logic to a second EJB with a void method annotated @Asynchronous and calling it from your init method.Torrez
You're right. It worked like a charm! What about to turn your comment into an answer?Coco
Answered as suggestedTorrez
T
3

Any bean annotated with javax.ejb.Singleton is an EJB and subject to the conditions that you quoted in your question.

You can circumvent the delay by moving your "database update task" logic to a second EJB:

@Stateless
public class DatabaseUpdater {

    @Resource
    private Datasource dataSource;

    // OR

    @PersistenceContext
    private EntityManager em;

    @javax.ejb.Asynchronous
    public void updateDatabase() {
        // beware of long running transaction timeouts in here!
        ...
    }

}

and then call it from your @Startup bean:

@Startup
@Singleton
public class StartupTask {

    @EJB
    private DatabaseUpdater databaseUpdater;

    @PostConstruct
    void init {
        databaseUpdater.updateDatabase();
    }

}
Torrez answered 1/5, 2019 at 3:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.