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 :

Rechargement d'une classe


Sujet :

Langage Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 27
    Par défaut Rechargement d'une classe
    Bonjour,

    Je vous explique mon soucis avant de vous mettre mon code :
    J'aimerais changer dynamiquement une classe. Pour cela, j'ai deux classes : la classe Chien et la classe Main. Chien est une classe bidon qui me sert à réaliser mes tests.

    La classe Main va modifier 'manuellement' la classe Chien (avec un FileWriter), la recompiler (avec un Process et un Runtime) et va lancer un ClassLoader pour recharger la classe.

    Mon problème c'est qu'une fois changer une fois, la classe Chien n'est apparemment plus changée ...

    Pour être plus clair, je vous présente le code :

    Chien.java :
    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
    public class Chien{
    	 int nbPattes;
    	 int nbYeux;
     
    	 public Chien(){
    	 nbPattes = 4;
    	 nbYeux = 2;
    	 }
     
    	 public void setNbPattes(int nbPattes){
    	 this.nbPattes = nbPattes;
    	 }
     
    	 public void setNbYeux(int nbYeux){
    	 this.nbYeux = nbYeux;
    	 }
     
    	 public int getNbPattes(){
    	 return this.nbPattes;
    	 }
     
    	 public int getNbYeux(){
    	 return this.nbYeux;
    	 }
    }
    Classe Main :
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    public class Main {
    	public static void main(String[] args){
     
    		int choix = 1;
    		while(choix <= 3) {
    			if (choix%2 == 0) {
    				FileWriter fw = null;
    				try {
    					File f = new File("Chien.java");
    					if (f.exists()) {
    						f.delete();
    					}
     
    					fw = new FileWriter(".\\src\\Chien.java");
     
    					String str = "public class Chien{\r\n\r\t";
    					str += " int nbPattes;\r\n\r\t";
    					str += " int nbYeux;\r\n\r\t";
    					str += " public Chien(){\r\n\r\t";
    					str += " nbPattes = 4;\r\n\r\t";
    					str += " nbYeux = 2;\r\n\r\t";
    					str += " }\r\n\r\t";
    					str += " public void setNbPattes(int nbPattes){\r\n\r\t";
    					str += " this.nbPattes = nbPattes;\r\n\r\t";
    					str += " }\r\n\r\t";
    					str += " public void setNbYeux(int nbYeux){\r\n\r\t";
    					str += " this.nbYeux = nbYeux;\r\n\r\t";
    					str += " }\r\n\r\t";
    					str += " public int getNbPattes(){\r\n\r\t";
    					str += " return this.nbPattes;\r\n\r\t";
    					str += " }\r\n\r\t";
    					str += " public int getNbYeux(){\r\n\r\t";
    					str += " return this.nbYeux;\r\n\r\t";
    					str += " }\r\n\r\t";
    					str += " }\r\n\r\t";
     
    					fw.write(str);
    					fw.close();
     
    					//Compilation du fichier créé
    					final Process process;
    					String file = "Chien.java";
    					try {				
    						if (System.getProperty("os.name").contains("indows")) {
    							process = Runtime.getRuntime().exec("javac "
    									+ "-d ./bin/"
    									+ " "
    									+ "-classpath "
    									+ "./bin"
    									+ " "
    									+ "./src/" + file);			
    						} else {
    							process = Runtime.getRuntime().exec("javac "
    									+ "-d ./bin/"
    									+ " "
    									+ "-classpath "
    									+ "./bin"
    									+ " "
    									+ "./src/" + file);	
    						}
     
    						//Le thread d'entrée
    						new Thread(){
    							public void run() {
    								try {
    									InputStream is = process.getInputStream();
    									BufferedReader br = new BufferedReader(new InputStreamReader(is),100);
    									for(;;){
    										String s = br.readLine();
    										if(s!=null)  
    											System.out.println("test " + s);
    										//s contient une ligne envoyée par le processus process
    									}
    								} catch (IOException ioe) {}
    							}
    						}.start();
     
    						//Le thread d'erreur
    						new Thread(){
    							public void run() {
    								try {
    									InputStream is = process.getErrorStream();
    									BufferedReader br = new BufferedReader(new InputStreamReader(is),100);
    									for(;;){
    										String s = br.readLine();
    										if(s!=null)  
    											System.out.println("line " + s);
    										//s contient une ligne erreur envoyée par le processus process
    									}
    								} catch (IOException ioe) {}				            
    							}
    						}.start();
     
    						try {
    							process.waitFor();
    						} catch (InterruptedException e1) {
    							// TODO Auto-generated catch block
    							e1.printStackTrace();
    						}
     
    					}catch (IOException zef) {
    						System.out.println("Error execution of process");
    					}
     
    				} catch (IOException e1) {
    					// TODO Auto-generated catch block
    					e1.printStackTrace();
    				}
     
    				//CLASSLOADER
    				Chien chienBienForme = null;
     
    				String repClasse="D:\\WorkSpaceEclipse\\TestClassLoader\\bin\\Chien.class";
    				File f = new File(repClasse);
    				if(f.exists()){
    					System.out.println("c'est cool " + f.getAbsolutePath());
    				}
    				System.out.println("Chargement par URLLoader");
    				try { 
    					URLClassLoader cc = new URLClassLoader(
    							new URL[] {f.toURI().toURL() }
    					);
     
    					String test = "Chien";
    					Class c = cc.loadClass(test);
    					chienBienForme = (Chien) c.newInstance();
    				}
    				catch(Exception e1) { System.out.println("!!!chargement 2: "+e1);}
    				//FINCLASSLOADER
     
     
    				//Chien chienBienForme = new Chien();
    				System.out.println("CHIEN BIEN FORME ? : nbPattes " + chienBienForme.getNbPattes() + " et nbYeux = " + chienBienForme.getNbYeux());
    				choix ++;
     
    			} else {
    //ON REND LE CHIEN MAL FORME
    //LA PROCEDURE EST LA MEME SAUF QUE NBPATTES = 10 et NBYEUX = 99
    				        .....
    					str += " nbPattes = 10;\r\n\r\t";
    					str += " nbYeux = 99;\r\n\r\t";
    					.....
     
    				System.out.println("CHIEN MAL FORME ? : nbPattes " + chienMalForme.getNbPattes() + " et nbYeux = " + chienMalForme.getNbYeux());
    				choix ++;
    			}
    		}
    	}
    }
    Voilà en gros mon problème. Si vous avez des suggestions ...
    Merci beaucoup pour votre future aide.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Il vous faut comprendre les modèle de délagation des classloader et le fonctionnement de l'assignation.

    "Chien" (utilisé dans le Main) est une classe chargée par le classloader principal et correspondant à votre code d'origine.

    c est une Classe qui porte le même nom que Chien et qui a le même package, mais pas le même classloader, car il sera chargé par le URLClassLoader. Ces deux classes ne sont pas les même, elles coexistent et ne sont pas assignables entre elle.

    Pour pouvoir assigner à Chien, il aurait fallu que la classe réécrite au vol hérite de Chien. Du style générer "class Chien444719 extends Chien". En java, en aucun cas une classe chargée en mémoire ne peut être changée par la suite.

    Tout ça suppose bien entendu que vous chargiez bien le nouveau .class, dans votre code ce n'est pas le cas. Le principe de délégation implique que URLClassLoader va demander à son classloader parent d'abord si il trouve la class, classloader parent qui trouvera votre Chien d'origine Votre .class ne sera jamais lu. D'ou l'utilité de l'extends (ou implements dans le cas d'une interface) et d'un nom unique.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 27
    Par défaut
    Merci beaucoup pour votre rapidité de réponse et surtout votre clareté.

    J'ai maintenant réellement compris à quoi servaient ces ClassLoader et leurs fonctionnements.

    Pour mon exemple, en passant par comme vous me l'avez suggéré, un 'extends' de la classe abstraite Chien, cela fonctionne parfaitement (pour l'instant, à voir avec le projet que je suis en train de réaliser).

    Merci encore.
    Florent.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Je me permet aussi de vous signaler qu'il existe des librairies pour générer directement le bytecode dont vous avez besoin et vous affranchir du compilateur, ce qui est en général utilisé par les application faisant de l'instrumentation de classes

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

Discussions similaires

  1. Comment recharger une JFrame dans une Class ActionListener
    Par swaby974 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 29/11/2012, 22h30
  2. Forcer la JVM à recharger une classe.
    Par Sierra3193 dans le forum Langage
    Réponses: 12
    Dernier message: 17/01/2009, 23h37
  3. Recharger une classe en cours d'exécution
    Par frites.saucisse dans le forum Général Python
    Réponses: 9
    Dernier message: 23/08/2008, 10h57
  4. recharger dynamiquement une classe
    Par orelero dans le forum Général Java
    Réponses: 4
    Dernier message: 02/10/2006, 14h09
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 18h21

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