«Неудовлетворенные зависимости» с UnsatisfiedResolutionException при попытке внедрить EJB в другой компонент - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь реализовать управляемый исполнитель Java EE ManagedExecutorService для отправки вызываемых задач, где каждая задача выполняет вызов внедренного метода bean.

Я использую класс Instance, чтобы сделатьконтейнер знает об объекте задачи, но при выполнении get() выдается следующее исключение:

Причина: javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Неудовлетворенные зависимости для типа MyTask с квалификаторами @ По умолчанию

Я запускаю это на WildFly 14.

Внедренный компонент:

@Stateless
public class MyBean {

    public void print() {
        System.out.println("MyBean printed");
    }
}

task:

@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 голосов
/ 07 марта 2019

Проблема в том, что с MyTask в качестве EJB-компонента, реализующего Callable , вы удалили сам класс MyTask из "bean-типа" этого bean-компонентаЭто означает, что он не может быть введен в @Inject MyTask xxx «клиент», согласно правилам в спецификации CDI 2.0 :

18.2.2.Типы компонентов сессионного компонента

Неограниченный набор типов компонентов для сессионного компонента содержит все локальные интерфейсы компонента и их суперинтерфейсы.Если сессионный компонент имеет представление без интерфейса, неограниченный набор типов компонентов содержит класс компонента и все суперклассы.Кроме того, java.lang.Object является типом bean-компонента для каждого сессионного компонента.

Именно поэтому Weld не находит действительный компонент MyTask для удовлетворения инъекции в ваш TestBean client.

Вы можете предоставить MyTask EJB представление без интерфейса, добавив аннотацию @LocalBean, например:

@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())

    // ...
}

См. здесь для быстрого ознакомления с представлением без интерфейса, а также this сообщение для дальнейшего обсуждения.

...