我正在努力弄清楚为什么我的EJB中的@Asynchronous方法实际上并没有异步调用。我正在使用CDI(带有beans.xml)在JBoss AS 7上运行JSF2项目,并使用Maven生成的简单.war包装。
EJB与.war一起打包,以及与之交互的JSF2托管bean。这是一个简单的@Stateless EJB。通过将它(通过@Inject)注入到调用其@Asynchronous方法的JSF2托管bean中来使用它。
它不是立即返回Future的@Asynchronous方法调用,而是同步执行,就好像它是一个普通的unproxied直接调用一样。无论我使用本地无接口视图还是本地业务接口来调用EJB,都是如此。
@Remote bean只支持@Asynchronous吗?如果是这样,它是否可以在.war包装内工作,或者我是否必须在EAR中打包EJB jar才能获得这个功能?
简化代码,例如,.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();
}
}
答案 0 :(得分:9)
JBoss AS 7.0.2默认情况下不支持@Asynchronous。你必须打开它。如果它没有打开,则没有警告或错误消息,异步方法只是同步执行。
是的,这是用户友好的。
要在这个所谓的已完成和已发布的*产品中启用这些功能,您必须使用“standalone-preview.xml”运行JBoss AS 7.0.2,例如:
bin/standalone.sh --server-config=standalone-preview.xml
或AS 7.1(测试版)或更高版本:
bin/standalone.sh --server-config=standalone-full.xml
...它可以异步调用异步方法。
更新:正如garcia-jj所述,从lite=true
删除standalone.xml
也会使异步EJB工作。