Я изо всех сил пытаюсь понять, почему метод @Asynchronous в моем EJB на самом деле не вызывается асинхронно. Я использую JBoss AS 7, используя CDI (с beans.xml) в проекте JSF2 с простой упаковкой .war, созданной Maven.
Компонент EJB упакован в файл .war вместе с взаимодействующими с ним управляемыми компонентами JSF2. Это простой EJB @Stateless. Он используется путем внедрения его (через @Inject) в управляемый компонент JSF2, который вызывает свой метод @Asynchronous.
Вместо того, чтобы вызов метода @Asynchronous немедленно возвращал Future, он выполняется синхронно, как если бы это был обычный прямой вызов без прокси. Это справедливо независимо от того, использую ли я локальное представление без интерфейса или локальный бизнес-интерфейс для вызова EJB.
Поддерживается ли @Asynchronous только для компонентов @Remote? Если да, то может ли он работать в упаковке .war или мне нужно упаковать банку EJB в EAR только для того, чтобы получить эту функцию?
Упрощенный код, например, с каждым классом в одном пакете в .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();
}
}