Conveniently, Transactionally and Legally Starting Runnables …With Java EE 6
EJB spec does not allow starting and managing threads:
The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups. [EJB 3.1 spec, page 599]
With Java EE 6 you don't have to create threads to execute a java.lang.Runnable
asynchronously. Just implement an Executor
as EJB 3.1:
import java.util.concurrent.Executor;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
@Stateless
public class TransactionalExecutor implements Executor{
@Override @Asynchronous
public void execute(Runnable command) {
command.run();
}
}
Now inject the TransactionalExecutor
as an Executor
(the implementation of the Executor is optional, you could also directly inject the bean):
@Stateless
public class SlowService {
@Inject
Executor executor;
public void invoke(){
Runnable command = new Runnable() {
@Override
public void run() {
//some heavy work to do
}
};
executor.execute(command);
}
}
The Java EE 6 solution happens to be less simpler, than comparable Java SE implementation :-).
The async-worker Maven 3 project was pushed into http://kenai.com/projects/javaee-patterns/.
[The example is an excerpt from the "Real World Java EE Patterns" book (Second Iteration), page 167 in, chapter "Async Worker"]
See you at airhacks.com!
Hi Adam
Is there a way to implement something like the fork-join in Java EE?
It is legal to extends the ForkJoinPool to manage the ForkJoinTasks ?
Posted by Daniel on September 10, 2012 at 08:05 PM CEST #
Brilliant!
Posted by David Blevins on September 15, 2012 at 12:00 AM CEST #
It seems that the fact that your TransactionalExecutor implements Executor is irrelevant: TransactionalExecutor could implement another interface or not implement an interface at all. The only relevant bits are that 1) TransactionalExecutor is an SLSB, 2) has a method (execute(), in your example) that takes the block of code to execute as an argument (in the form of a Runnable, in your example) and that 3) that method is annotated with @Asynchronous. Correct?
Posted by Gerald Loeffler on September 22, 2012 at 03:42 PM CEST #
@Gerald,
+1. Forget about the Executor. It is just a nice extension,
thanks for your comment,
adam
Posted by Adam Bien on September 22, 2012 at 07:35 PM CEST #
Hi Adam,
I'm looking for a way to do the same in Java EE 5? Is JMS/MDB the only way to achieve it cleanly?
Posted by kweveen on October 24, 2012 at 04:59 PM CEST #
Adam i have a error running example in jboss 7.1
Caused by: java.lang.SecurityException: Prohibited package name: java.util.concurrent
Posted by Raul on December 04, 2012 at 11:27 PM CET #
could you please update the link? http://kenai.com/projects/javaee-patterns/
Posted by erick on November 07, 2017 at 10:28 PM CET #