[CDI] Exception lors du lookup dynamique
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
Code:
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;
} |
Et son literal RandomNumberLiteral
Code:
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;
}
} |
La méthode d'un bean factory (POJO):
Code:
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);
} |
L'utilisation du dynamic lookup (le resultat du select n'est ni ambiguous ni unsatisfied):
Code:
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());
}
} |
La première instruction fonctionne très bien mais pour la seconde, voici l'exception levée:
Code:
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