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
}
} |
@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();
}
} |
@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
}
});
}
} |
@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
}
});
}
}