I'm struggling to figure out why an @Asynchronous method in my EJB isn't actually being invoked asynchronously. I'm running on JBoss AS 7 using CDI (with beans.xml) in a JSF2 project with simple .war packaging produced by Maven.
The EJB is packaged in a .war along with the JSF2 managed beans that interact with it. It's a simple @Stateless EJB. It's used by injecting it (via @Inject) into a JSF2 managed bean that invokes its @Asynchronous method.
Instead of the @Asynchronous method invocation returning a Future immediately, it executes synchronously as if it were an ordinary unproxied direct call. This is true whether I use a local no-interface view or a local business interface to invoke the EJB.
Is @Asynchronous only supported for @Remote beans? If so, can it work within .war packaging or do I have to package an EJB jar in an EAR just to get this one feature?
Simplified code for example's sake, with each class in the same package in a .war:
public interface SomeEJB {
public Future<Void> doSomething();
}
@Stateless
@Local(SomeEJB.class)
public class SomeEJBImpl implements SomeEJB {
@Asynchronous
@Override
public Future<Void> doSomething() {
// Spend a while doing work
// then:
return new AsyncResult<Void>(null);
}
}
@Named
@RequestScoped
public class JSFBean {
@Inject private transient SomeEJB someEJB;
private Future<Void> progress;
// Called from JSF2, starts work and re-displays page
public String startWorkAction() {
// This call SHOULD return a Future immediately. Instead it blocks
// until doWork() completes.
progress = someEJB.doWork();
}
public Boolean isDone() {
return progress != null && progress.isDone();
}
}