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

Langage Java Discussion :

Comment executer une liste de méthodes passées en argument


Sujet :

Langage Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut Comment executer une liste de méthodes passées en argument
    Pour réinitialiser une Bdd j'ai une jsp qui propose une réinit de tout ou partie. Donc suivant l'option choisie (10 option) je ferai une sauvegarde et une réinit de ou des tables concernées. La réint de chaque table est associée à une méthode du même nom, toutes les méthodes sont dans la même class iniBdd. Donc je je proposais d'écrire la class générique en lui passant en argument un tableau des tables à réinitialiser:
    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
     
    public class Bdd_initialisation {<div style="margin-left:40px">
        public static void main(Statement stmt,HttpSession session,String[] tbl){
     
        StringBuffer export = new StringBuffer();
        for(int i=1;i=tbl.length();i++)
        {//class de sauvegarde
        export = export.append("--table "+tbl[i]+"\n--");
        export = export.append(librairie.FormatageSQL.main(stmt,tbl[i]);
        export = export.append("--");
        //méthode de réint de la table
        // -> une méthode par table
        // ttes les méthodes (50) sont dans la même class
        // nom de table = nom de méthode
        librairie.InitBdd.  nom de la table -> tbl[i] (stmt);
        }
        session.setAttribute("export",export.toString());
        }</div>}
    Comment écrire la ligne en rouge ??
    Merci

  2. #2
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Comment lancer dynamiquement une méthode donnée d'un objet ?

    ... cependant, quand on n'a jamais entendu parler de ces concepts java de reflexivité, je ne sais pas si c'est très clair. Regarde d'autres liens sur le sujet (il y a d'autres informations dans la ) et si tu y arrives pas on essaiera de te donner un exemple plus proche de ce que tu cherches.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    http://ricky81.developpez.com/tutori...pi/reflection/


    PS: merci de penser aux balises code (bouton # au dessus de la boite de saisie)
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Merci de vos réponses
    Pour les balises je ne pensais pas en écrire autan.
    Donc suivant vos indications et la FAQ j'ai écris ce qui suit mais j'ai tjs un pb c'est l'apprentissage:

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
     
    import java.sql.Statement;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import java.lang.reflect.*;
     
    public class Bdd_initialisation_1 {
     
    	public static void main(Statement stmt,HttpSession session,HttpServletRequest a){
    		String tbl = "";
    		Class c = null;
    		try {c = Class.forName("librairie.Init_bdd");
    			} catch (ClassNotFoundException e1) {e1.printStackTrace();}
    		Object[] args = {stmt};
     
    		if(a.getParameter("c1")!=null)
    			{tbl ="f15"; 
    			//attendu -> librairie.Init_bdd.f15(stmt);
    			 try{administration.Bdd_initialisation_1.lancerMethode_2(c, args, tbl);}
    			 catch (final Exception e){e.printStackTrace();};
     
    			}
     
    	}
     
     
     
    	public static Object lancerMethode_2(Class c, Object[] args, String nomMethode) throws Exception
    	{Class[] paramTypes = null;
    	 if(args != null)
    	   	{paramTypes = new Class[args.length];
    	   	for(int i=0;i<args.length;++i)
    	   		{paramTypes[i] = args[i].getClass();}
    	   	}
    	   //System.out.println(obj.getClass());
    	   Method m = c.getMethod(nomMethode,paramTypes);
     
    	   return m.invoke(c,args);
    	}
     
    }
    tout semble correcte mais j'ai l'exception suivante et là je ne pige pas:

    java.lang.NoSuchMethodException: librairie.Init_bdd.f15(com.mysql.jdbc.Statement)
    at java.lang.Class.getMethod(Unknown Source)

    car la méthode à lancer est : librairie.Init_bdd.f15(stmt)

    Merci pour le coups de pouce

  5. #5
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    Comme te le dit le texte de l'exception, la JVM ne trouve pas une méthode appelé f15 dans la classe Init_Bdd et qui prend un com.mysql.jdbc.Statement comme seul paramètre.
    Il faut vérifier ça dans la classe Init_Bdd ou encore en poster le code ici.

    Bonne chance.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Là justement le bas blesse car la class/méthode appelée est celle-ci:

    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
     
    package librairie;
     
    import java.sql.SQLException;
    import java.sql.Statement;
    import javax.servlet.http.HttpSession;
     
    public class Init_bdd {
     
    	public static void f15( Statement stmt){
    		String sql = "DROP TABLE IF EXISTS f15";
    		try{stmt.execute(sql);}catch(final SQLException e){;}	
    			sql = "CREATE TABLE `f15` ( "
    				 +"`LOCAL` varchar(25) default NULL, "
    				 +"`DTE_DEB` date default '0000-00-00', "
    				 +"`CODE_EMAT8` varchar(8) default NULL, "
    				 +"`DTE_FIN` date default '0000-00-00', "
    				 +"`DTO` int(3) default '0', "
    				 +"`REALISE` int(3) default '0', "
    				 +"`DTE_MAJ` date default '0000-00-00', "
    				 +"`CLE` mediumint(9) NOT NULL auto_increment, "
    				 +"PRIMARY KEY  (`CLE`) "
    				 +") ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ";
    		try{stmt.execute(sql);}catch(final SQLException e){System.out.println("Init_bdd: f15"+sql);}		
    	}
    ......
    Où est le bug?

  7. #7
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Je vois que tu commences à apprendre de jongler avec la reflexivité ! et ses pièges !

    Ici, je pense que cela vient de la façon dont tu détermines les arguments de la méthode recherchée.

    Tu fais {paramTypes[i] = args[i].getClass();}, et, d'après le message d'erreur, tu obtiens un com.mysql.jdbc.Statement (ce qui est, d'ailleurs, un peu étonnant, mais enfin...).

    Or il y a de grandes chances pour que cet argument soit un... java.sql.Statement, tout simplement. Il doit y avoir un micmac entre les méthodes déclarées, implémentées, etc.

    Tu ne peux pas t'adapter à tout. Que tu définisses le nom des méthodes en fonction d'une table ou d'une base, soit. Mais que, en plus, les arguments varient selon cette table, la base, l'âge du capitaine, c'est chercher les ennuis. Donnes toi plutôt une liste de paramètres connue d'avance.

    Et, si tu ne peux pas, parlons un peu plus de la raison qui te pousse à changer le nom des méthodes en fonction de la table.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Suite à l'aiguillage vers la faq je n'ai fait que du pompage et cherche à comprendre le mécanisme. Ma class contient 40 méthodes à 1 paramètre donc

    Tu fais {paramTypes[i] = args[i].getClass();},
    ne contient que stmt donc j'ai supprimé cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	public static Object lancerMethode_2(Class c, Object args, String nomMethode) throws Exception
    	{Class paramTypes = null;
    	 if(args != null)
    	   	{paramTypes = args.getClass();}
    	   Method m = c.getMethod(nomMethode,paramTypes);	   
    	   return m.invoke(c,args);
    	}
    mais résultat idem
    Je pense que le pb vient du paramètre mais je cale.
    On verra demain

  9. #9
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    En gros, l'erreur dans ton code réside dans le fait que tu cherches à trouver par reflection dans la classe Init_Bdd une méthode nommé f15 et qui prend en paramètre un com.mysql.jdbc.Statement, sauf que la méthode Init_Bdd.f15 que tu as défini prend un java.sql.Statement comme paramètre. C'est pour ça que ça bloque. Il faudrait travailler avec le même type de Statement et dans Init_Bdd.f15 et dans la partie reflection.

    Bonne chance.

  10. #10
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par gifffftane Voir le message
    Tu fais {paramTypes[i] = args[i].getClass();}, et, d'après le message d'erreur, tu obtiens un com.mysql.jdbc.Statement (ce qui est, d'ailleurs, un peu étonnant, mais enfin...).
    Non ce n'est pas étonnant : il doit utiliser le getClass() sur un objet Statement qu'il a créé via sa connexion, et dont le type réel correspond à une classe de son driver JDBC...


    Pour résoudre le problème il faut bien sûr utiliser le bon type (celui déclaré dans la méthode) ou rechercher la meilleure méthode correspondante.

    Il y a donc 2 solutions :
    1. Si toutes les méthodes attendent un Statement comme je le pense, il suffit de le passer en dur :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Method m = c.getMethod(nomMethode, Statement.class);
    2. Sinon c'est plus compliqué, et il faut utiliser Class.getMethods() pour rechercher les méthode du même nom et vérifier que les arguments correspondent avec la méthode isAssignableFrom()...


    Citation Envoyé par gifffftane Voir le message
    Et, si tu ne peux pas, parlons un peu plus de la raison qui te pousse à changer le nom des méthodes en fonction de la table.
    +1

    Il serait surement plus simple de faire une méthode générique qui prendrait en paramètre la requête SQL a exécuté...

    Sinon attention au bloc catch vide (c'est un truc à perdre un temps fou parce qu'une erreur est simplement "ignoré"), et libère tes ressources !

    a++

  11. #11
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    +1

    Il serait surement plus simple de faire une méthode générique qui prendrait en paramètre la requête SQL a exécuté...
    Et dans ce cas il serait encore plus judicieux d'utiliser une interface, comme ça tu n'as plus du tout besoin de réflexivité

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Explications du pourquoi du comment:

    Tout d'abord merci, la solution Statement.class fonctionne nickel.

    Envoyé par gifffftane Voir le message
    Et, si tu ne peux pas, parlons un peu plus de la raison qui te pousse à changer le nom des méthodes en fonction de la table.
    Je suis sur une appli de gestion et d'entretien dont les tables sont initialisées via cette class par appel des méthodes. La mise à jour des données s'effectue par import de fichiers txt via des class qui triture données et tables. Comme tout un éventail de possibilité d'import est offert à l'administrateur, les tables concernées ne sont pas tjs les mêmes et de plus s'ajoute le pb de changement d'année avec un raz au coups par coups suivant l'état d'avancement.
    Donc j'ai choisi la simplicité mais j'en suis à 450 fichiers et je n'ai pas fini !!!

    , et libère tes ressources !
    Question philosophique sur la libération des ressources. Mon appli est construite autour d'une jsp et d'une servlet qui se chargent de l'aiguillage sur les class et sous-jsp. Avant la clôture de la servlet ttes les ressources sont libérées donc vaut-il mieux le faire au coups par coups mais si j'ai une exception je passerai outre ou le faire après le seul et unique getRequestDispatcher.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment initialiser une liste dans la méthode reset()
    Par don'de dans le forum Struts 1
    Réponses: 10
    Dernier message: 19/03/2007, 21h17
  2. Réponses: 5
    Dernier message: 29/09/2005, 14h37
  3. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46
  4. Réponses: 4
    Dernier message: 03/12/2004, 11h18
  5. [PDFBox]Comment manipuler une LIST
    Par marcotop dans le forum Documents
    Réponses: 11
    Dernier message: 27/08/2004, 15h46

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