我正在尝试实现Java EE的托管执行器ManagedExecutorService
来提交可调用任务,其中每个任务都调用一个注入的bean方法。
我正在使用Instance
类使容器知道任务对象,但是当执行get()
时会引发以下异常:
由于:javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException:WELD-001334: 带有限定符@Default的MyTask类型的依赖关系未满足
我正在WildFly 14上运行它。
注入的豆子:
@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());
}
}
}
为什么会引发异常以及如何解决此问题?类路径中缺少库吗?
答案 0 :(得分:1)
问题在于,使用 MyTask 作为实现 Callable 的EJB,您已经将 MyTask 类本身从“ bean类型”中删除了。 CDI 2.0 spec中的规则,表示不能将其注入@Inject MyTask xxx
“客户端”:
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())
// ...
}