@Asynchronous does not work from inside the same EJB

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

3 thoughts on “@Asynchronous does not work from inside the same EJB

  1. 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
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *