Je suis en train de mettre en œuvre l'exécuteur géré de Java EE ManagedExecutorService
à soumettre des tâches appelables, où chaque tâche fait un appel à une méthode de haricot injectée.
J'utilise la Instance
classe pour rendre le conteneur au courant de l'objet de la tâche, mais quand get()
est exécuté est lancé l'exception suivante:
Causée par: javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: dépendances non satisfaites pour le type MyTask avec des qualificatifs @default
Je suis en cela sur wildfly 14.
La fève injectée:
@Stateless
public class MyBean {
public void print() {
System.out.println("MyBean printed");
}
}
La tâche:
@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";
}
}
La tâche invocateur:
@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());
}
}
}
Pourquoi l'exception jetée et comment résoudre ce problème? Y at-il une bibliothèque manquante dans le classpath?
Le problème est que , avec MyTask comme EJB la mise en œuvre appelable , vous avez supprimé la MyTask classe elle - même du « type de haricot » de ce haricot, ce qui signifie qu'il ne peut pas être injecté dans @Inject MyTask xxx
« client », selon les règles du CDI 2.0 spec :
18.2.2. types de bean session Bean
L'ensemble sans restriction des types de haricots pour un haricot de session contient toutes les interfaces locales du haricot et leurs superinterfaces. Si le grain de session a une vue sans interface, l'ensemble sans restriction des types de haricots contient la classe de haricots et de tous superclasse. En outre, java.lang.Object est un type de haricot de chaque grain de session.
Voilà pourquoi Weld ne trouve pas valide MyTask haricots pour satisfaire l'injection dans votre TestBean client.
Vous pouvez donner l' MyTask EJB une vue sans interface en ajoutant l' @LocalBean
annotation, par exemple:
@Stateless
@LocalBean
public class MyTask implements Callable<String> {
Ou, vous pouvez supprimer le implements Callable
et refactor comme:
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())
// ...
}
Voir ici pour une référence rapide sur la vue sans interface, ainsi que ce poste pour une discussion plus approfondie.