I recently needed to start a method asynchronously on the server start up.
I came up with this code (pseudocode):
@Singleton @Startup public StartupEJB { @PostConstruct private void postConstruct() { worker(); } @Asynchronous public void worker() { // Do something heavy } } |
This approach failed, the worker() method was not executed asynchronously.
I then found out that the Application Server (in my case JBoss) calls the method directly when it is located inside the same EJB: source.
The solution was to use a seperate EJB that launched the worker Thread:
@Stateless public class ExecutorBean { @Asynchronous public void execute(Runnable command) { command.run(); } } |
and
@Singleton @Startup public StartupEJB { @EJB ExecutorBean executorBean; @PostConstruct private void postConstruct() { worker(); } public void worker() { executorBean.execute(new Runnable() { @Override public void run() { // Do something heavy } }); } } |
You saved my life 🙂
Thank you so much !
Is a local interface and self reference to invoke container management not sufficient. As far as I know starting threads yourself is not allowed within JavaEE containers!
Following code works async within stateless beans, but should also work within application scope bean.
@Singleton
@LocalBean
@Startup
public StartupEJB {
@EJB
private StartupEJB me;
@PostConstruct
private void postConstruct() {
me.worker();
}
@Asynchronous
public void worker() {
// Do something heavy
}
}
Since the EJB is accessed through the injected proxy it will still work, nice solution!