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 : 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;
 
}
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
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 : 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);
}
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
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 : 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