Bonjour à tous,
Je me heurte à un bug soit de mon code soit de l'implémentation CDI de mon serveur TomEE.
En effet, mon dynamic lookup via CDI (Instance) ne fonctionne pas correctement.
Plus particulièrement, j'ai constaté que le dynamic lookup ne fonctionne pas lorsque l'on utilise une méthode @Produces tout en ayant l'InjectionPoint comme paramètre.
Je vais prendre un exemple simple de génération aléatoire d'un Integer selon une borne min et max:
Voici le Qualifier @RandomNumber
Et son literal RandomNumberLiteral
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 @Qualifier @Retention(RUNTIME) @Target({ METHOD, FIELD, PARAMETER, TYPE }) public @interface RandomNumber { @Nonbinding int min() default 0; @Nonbinding int max() default 10; }
La méthode d'un bean factory (POJO):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class RandomNumberLiteral extends AnnotationLiteral<RandomNumber> implements RandomNumber { private final int min; private final int max; public RandomNumberLiteral(final int min, final int max) { this.min = min; this.max = max; } @Override public int max() { return this.max; } @Override public int min() { return this.min; } }
L'utilisation du dynamic lookup (le resultat du select n'est ni ambiguous ni unsatisfied):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 @Produces @RandomNumber public Integer producesNumber(final InjectionPoint ip) { final int min = ip.getAnnotated().getAnnotation(RandomNumber.class).min(); final int max = ip.getAnnotated().getAnnotation(RandomNumber.class).max(); return (new Random().nextInt((max - min) + 1) + min); }
La première instruction fonctionne très bien mais pour la seconde, voici l'exception levée:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public class Test { @Inject @RandomNumber(min = 20, max = 50) private Integer random; @Inject @Any private Instance<Integer> randomInstance; public void test() { System.out.println("Random1: " + this.random); System.out.println("Random2: " + this.randomInstance.select(new RandomNumberLiteral(20, 50)).get()); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: java.util.EmptyStackException at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:363) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:283) blablabla Caused by: java.util.EmptyStackException at java.util.Stack.peek(Stack.java:102) at org.apache.webbeans.component.InjectionPointBean.createInstance(InjectionPointBean.java:83) at org.apache.webbeans.component.InjectionPointBean.createInstance(InjectionPointBean.java:28) at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:186) at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:70) at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:132) at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:872) at org.apache.webbeans.inject.InjectableMethods.doInjection(InjectableMethods.java:96) at org.apache.webbeans.component.ProducerMethodBean.createDefaultInstance(ProducerMethodBean.java:161) at org.apache.webbeans.component.ProducerMethodBean.createInstance(ProducerMethodBean.java:123) at org.apache.webbeans.component.AbstractOwbBean.createNewInstance(AbstractOwbBean.java:233) at org.apache.webbeans.portable.creation.AbstractProducer.produce(AbstractProducer.java:77) at org.apache.webbeans.component.InjectionTargetWrapper.produce(InjectionTargetWrapper.java:133) at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:180) at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:70) at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:132) at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:872) at org.apache.webbeans.inject.instance.InstanceImpl.get(InstanceImpl.java:126)
Voila c'est vraiment embêtant car je veux utiliser cela pour des fonctionnalités plus complexes mais j'ai l'impression que c'est foutu.
Si un Java Champion pouvait venir me sauver je lui serai à jamais reconnaissant!
Merci beaucoup
Partager