IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java EE Discussion :

[CDI] Exception lors du lookup dynamique


Sujet :

Java EE

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut [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 : 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

  2. #2
    Membre régulier
    Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 42
    Points : 96
    Points
    96
    Par défaut
    Dans ta méthode producer, tu t'intéresses au point d'injection ip, mais dans le cas de l'injection dynamique, ce point d'injection est en fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @Inject
    @Any
    private Instance<Integer> randomInstance;
    Lequel ne définit que les annotations Inject et Any, ce qui signifie que l'appel "ip.getAnnotated().getAnnotation(RandomNumber.class)" te rendra invariablement la valeur null, malheureusement.


    Essaie peut être cette implémentation qui, certes, n'est pas très belle mais répond peut être à ton soucis :

    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
     
    public class RandomNumberFactory {
       @Produces
       @RandomNumber
       public Integer producesNumber(final InjectionPoint ip) {
     
          final Set<Annotation> qualifiers = ip.getQualifiers();
          for(final Annotation annotation : qualifiers ) {
             if( annotation instanceof RandomNumber ) {
                final RandomNumber randomNumber = RandomNumber.class.cast(annotation);
                final int min = randomNumber.min();
                final int max = randomNumber.max();
     
                return (new Random().nextInt((max - min) + 1) + min);
             }
          }
     
          return null;
        }
    }

  3. #3
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    Salut et désolé pour cette année de retard. Je suis retombé sur ce topic que j'avais complètement oublié et j'ai été surpris que quelqu'un m'ait répondu.
    Merci pour ta réponse, je n'avais pas pensé à l'inspection des qualifier avec l'injection point!
    A+!

Discussions similaires

  1. Exception lors de l'impression
    Par lilou77 dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 08/12/2005, 10h56
  2. Réponses: 4
    Dernier message: 06/09/2005, 09h58
  3. Réponses: 9
    Dernier message: 31/05/2005, 10h05
  4. [Exception]Lors d'un validate sur un jframe
    Par cameleon2002 dans le forum Agents de placement/Fenêtres
    Réponses: 12
    Dernier message: 02/05/2005, 11h27
  5. [JDBC] SQL Exception lors d'une Query !
    Par Castagnems dans le forum JDBC
    Réponses: 5
    Dernier message: 30/04/2004, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo