adam bien's blog

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!