尝试将EJB注入另一个组件时,带有UnsatisfiedResolutionException的“不满意的依赖项”

时间:2019-03-03 15:36:56

标签: java java-ee ejb

我正在尝试实现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());
        }

    }
}

为什么会引发异常以及如何解决此问题?类路径中缺少库吗?

1 个答案:

答案 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())

    // ...
}

有关无界面视图的快速参考,请参见here,有关更多讨论,请参见this帖子。