问题描述
我正在尝试实现 Java EE 的托管执行程序ManagedExecutorService
来提交可调用任务,其中每个任务都会调用注入的 bean 方法。
我正在使用Instance
类让容器知道任务对象,但是当get()
被执行时,会抛出以下异常:
引起:javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: 不满足类型 MyTask 与限定符 @Default 的依赖关系
我在 WildFly 14 上运行它。
注入的bean:
@Stateless
public class MyBean {
public void print() {
System.out.println("MyBean printed");
}
}
任务:
@Stateless
public class MyTask implements Callable<String> {
@Inject
MyBean myBean;
@Override
public String call() throws Exception {
System.out.println("MyTask called");
myBean.print();
return "Task called";
}
}
任务调用者:
@Stateless
public class TestBean {
@Inject
Instance<MyTask> myTaskInstance;
@Resource
private ManagedExecutorService executor;
public void test() throws InterruptedException, ExecutionException {
List<Callable<String>> tasks = new ArrayList<>();
MyTask task = myTaskInstance.get(); // <------- Exception is thrown here
tasks.add(task);
MyTask task2 = myTaskInstance.get();
tasks.add(task2);
List<Future<String>> taskResults = null;
taskResults = executor.invokeAll(tasks);
List<String> results = new ArrayList<>();
for(Future<String> taskResult : taskResults) {
results.add(taskResult.get());
}
}
}
为什么会抛出异常以及如何解决这个问题? 类路径中是否缺少库?
1楼
问题在于,使用MyTask作为实现Callable的 EJB,您已经从这个 bean 的“bean 类型”中删除了MyTask类本身,这意味着它不能被注入到@Inject MyTask xxx
“client”,根据:
18.2.2. 会话 bean 的 bean 类型
会话 bean 的不受限制的 bean 类型集包含 bean 的所有本地接口及其超接口。 如果会话 bean 具有无接口视图,则不受限制的 bean 类型集包含 bean 类和所有超类。 另外,java.lang.Object 是每个会话 bean 的 bean 类型。
这就是 Weld 找不到有效MyTask bean 来满足注入TestBean客户端的原因。
您可以通过添加@LocalBean
注释为MyTask EJB 提供无接口视图,例如:
@Stateless
@LocalBean
public class MyTask implements Callable<String> {
或者,您可以删除implements Callable
和重构,如:
public class MyTask {
@Inject
MyBean myBean;
MyCallable callable = new MyCallable();
public Callable getCallable() {
return callable;
}
private class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("MyTask called");
myBean.print();
return "Task called";
}
}
}
public class TestBean {
// ...
MyTask task = myTaskInstance.get();
tasks.add(task.getCallable())
// ...
}
有关无接口视图的快速参考,请参见,以及有关更多讨论的文章。