Introspection (ivoke)

Résolu
cs_tenthor Messages postés 55 Date d'inscription dimanche 13 novembre 2005 Statut Membre Dernière intervention 29 juin 2007 - 9 mai 2007 à 17:15
cs_tenthor Messages postés 55 Date d'inscription dimanche 13 novembre 2005 Statut Membre Dernière intervention 29 juin 2007 - 10 mai 2007 à 10:24
Bonjour a tous !

Je développe un bout de code en ce moment, qui utilise l'introspection. J'ai un probleme avec la méthode invoke(Object obj, Object... args).

Voici ce que j'ai fait :

public static Object getGestionnaire(Object obj, String champ)
    {
        Object retour = null;
       
        Class classe = obj.getClass();
        Method getGestionnaire = null;
        try
        {
            getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), null);
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
       
        if (getGestionnaire != null)
        {
            Object gestionnaire = null;
            try
            {
                getGestionnaire.invoke(gestionnaire, null);
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            retour = getObjectFromGestionnaire(gestionnaire);
        }
       
        return retour;
    }

En fait, au niveau de l'exécution du invoke, j'ai une exception qui générée :
Exception in thread "main" java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at testAvecIntrospection.Impression.getGestionnaire(Impression.java:86)
    ...

L'objet Method nommé getGestionnaire n'est pourtant pas null puisqu'il y a un test juste avant.
Par contre l'Object gestionnaire, et le tableau d'arguments sont null. Mais dans la doc java il est dit :
    If the number of formal parameters required by the underlying method is
0, the supplied
args
array may be of length 0 or null.
Je suppose donc que le problème vient de gestionnaire. Moi j'avais cru comprendre que le resultat de la méthode invoke aller être mit dans le premier paramètre de invoke, non ?

En fait je crois que je n'ai pas bien compris comment s'utilise la méthode invoke(....)
Quelqu'un pourrait-il me l'expliquer s'il vous plait ?

Merci de votre attention,
Tenthor.

5 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
10 mai 2007 à 10:14
Salut,

ton objet gestionnaire ne sert absolument à rien :P il te faut le remplacer par obj qui est censé etre l'objet contenant la méthode getGestionnaire

public static Object getGestionnaire(Object obj, String champ)
    {
        Object retour = null;
       
        Class classe = obj.getClass();
        Method getGestionnaire = null;
        try
        {
            getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), new Class[]{});
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
       
        if (getGestionnaire != null)
        {
            <strike>Object gestionnaire = new Object();</strike>
            try
            {
                getGestionnaire.invoke( obj , new Object[]{});
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            retour = getObjectFromGestionnaire(gestionnaire);
        }
       
        return retour;
    }

mais attention ici tu invoke ine méthode de type 'void getGestionnaire()', donc je ne sais pas ce que tu fais dans ta méthode getObjectFromGestionnaire(gestionnaire) mais si ton but et de récupérer le retour de la méthode getGestionnaire (soit avec une signature genre 'Object getGestionnaire()' il te faut changer ton code par :

public static Object getGestionnaire(Object obj, String champ)
    {
        Object retour = null;
       
        Class classe = obj.getClass();
        Method getGestionnaire = null;
        try
        {
            getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), new Class[]{});
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
       
        if (getGestionnaire != null)
        {

            <strike>Object gestionnaire = new Object();</strike>
            try
            {
                retour = getGestionnaire.invoke(obj, new Object[]{});
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            <strike>retour = getObjectFromGestionnaire(gestionnaire);</strike>
        }
       
        return retour;
    }

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
3
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
9 mai 2007 à 18:02
Salut,

ne met pas null mais un tableau vide

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
9 mai 2007 à 18:05
Salut,

soit   getGestionnaire.invoke(gestionnaire, new Object [] {});
et si tu veux etre propre remplace ta ligne
 getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), null);
par
getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), new Class[] {});

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
cs_tenthor Messages postés 55 Date d'inscription dimanche 13 novembre 2005 Statut Membre Dernière intervention 29 juin 2007 1
10 mai 2007 à 09:55
Bonjour et merci d'avoir répondu !

Alors voilà suite à vos conseils, j'ai procédé à quelques modifications :

public static Object getGestionnaire(Object obj, String champ)
    {
        Object retour = null;
       
        Class classe = obj.getClass();
        Method getGestionnaire = null;
        try
        {
            getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), new Class[]{});
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
       
        if (getGestionnaire != null)
        {
            Object gestionnaire = new Object();
            try
            {
                getGestionnaire.invoke(gestionnaire, new Object[]{});
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            retour = getObjectFromGestionnaire(gestionnaire);
        }
       
        return retour;
    }

Donc après avoir rajouté les tableaux vides en paramètres (en bleu), j'avais toujours une exception de type NullPointerException qui été générée.
J'ai donc décidé d'instancier la variable gestionnaire avec Object gestionnaire = new Object(); (en rouge).
Mais maintenant j'ai une autre exception qui générée à l'exécution (au niveau de la ligne en vert) :
java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at testAvecIntrospection.Impression.getGestionnaire(Impression.java:88)
    ...
Je ne comprend pas trop, j'ai l'impression que l'argument gestionnaire qui est passé en paramètre n'est pas du bon type. Mais pourtant tous les objets héritent de la classe Object, alors je ne comprend pas trop, peut-être que je me trompe encore une fois. Décidément l'introspection n'est pas facile !

Encore une fois merci, et j'attends à nouveau de vos nouvelles pour la suite.
Merci de votre attention,
Tenthor.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_tenthor Messages postés 55 Date d'inscription dimanche 13 novembre 2005 Statut Membre Dernière intervention 29 juin 2007 1
10 mai 2007 à 10:24
Ok et un grand merci !!! Ca fonctionne !

En fait la méthode getGestionnaire me renvoi le gestionnaire. En fait j'ai mal compris la doc java ! Je pensais que le résultat de ma méthode getGestionnaire, allait êter mit dans l'objet gestionnaire que je passé en paramètre ! Mais la dic dit pourtant :
* Parameters: : <dd>
obj
- the object the underlying method is invoked from<dd>
args
- the arguments used for the method call
C'est donc moi qui est mal compris ! Voici ce que ca donna maintenant :

public static Object getGestionnaire(Object obj, String champ)
    {
        Object retour = null;
       
        Class classe = obj.getClass();
        Method getGestionnaire = null;
        try
        {
            getGestionnaire = classe.getMethod("getGestionnaire"+METString.premiereLettreMajuscule(champ), new Class[]{});
        } catch (SecurityException e)
        {
            e.printStackTrace();
        } catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
       
        if (getGestionnaire != null)
        {
            Object gestionnaire = null;
            try
            {
                gestionnaire = getGestionnaire.invoke( obj , new Object[]{});
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            retour = getObjectFromGestionnaire(gestionnaire);
        }
       
        return retour;
    }

Encore une fois un grand merci !
0
Rejoignez-nous