Exercices dirigés associés au cours sur les chargeurs de classes.

 

Depuis Bluej, l'archive à télécharger ed_classloader_a_completer.jar (puis ouvrir non_bluej ...., selon la procédure habituelle)

(en salle d'ED 31-3-XX, utilisez enregistrez la cible sous ...)

 

Question1 : Une archive utiles.jar présente à cette URL http://jfod.cnam.fr/progAvancee/classes/utiles.jar ,
contient au moins la classe UneClasse dont le code source ressemble à celle de votre répertoire, seul le message du bloc statique diffère

public class UneClasse{
  
  public static void main(String[] args){
    for(String s : args)
      System.out.print(s + " ");
      
    System.out.println();
  }
  
static{
  System.out.println("bloc static de UneClasse, répertoire ED ...");
}
}

Complétez la méthode main de la classe Question1 afin de charger une classe depuis cette archive et d'exécuter par introspection la méthode main en utilisant la ligne de commande suivante :

Charger la classe UneClasse selon cet ordre :

  1. http://jfod.cnam.fr/progAvancee/classes/
  2. http://jfod.cnam.fr/progAvancee/classes/utiles.jar
  3. "le classpath"
  4. "le bootclasspath"

Trace obtenue :

UneClasse : execution du bloc staticUneClasse.main : a b c

 

Vérifiez que deux appels de la méthode forName (ou plus) exécute bien une seule fois le bloc statique de la classe UneClasse

 

Question2 : Proposez votre propre chargeur de classe

Charger la classe UneClasse depuis et selon cet ordre :

  1. votre chargeur de classe (le répertoire courant)
  2. http://jfod.cnam.fr/progAvancee/classes/
  3. http://jfod.cnam.fr/progAvancee/classes/utiles.jar
  4. "le classpath"
  5. "le bootclasspath"

 

Trace obtenue

bloc static de UneClasse, répertoire ED ...
a b c

Vérifiez avec l'affichage résultant que cet ordre est bien respecté

Changer l'ordre de chargement :

  1. http://jfod.cnam.fr/progAvancee/classes/
  2. http://jfod.cnam.fr/progAvancee/classes/utiles.jar
  3. votre chargeur de classe (le répertoire courant)
  4. "le classpath"
  5. "le bootclasspath"

 

Question3 : Créez deux instances de votre chargeur de classes

Le chargeur1 charge la classe A

Le chargeur2 charge les classes A et B

 

Exécuter la méthode main de la classe B issue du chargeur de classe chargeur2, dans Question3

Le programme à compléter, méthode main de la classe Question3

ClassLoader c1 = new MonChargeurDeClasse();
ClassLoader c2 = new MonChargeurDeClasse();

Class<?> classeA_c1 = Class.forName("A", true, c1);

Class<?> classeA_c2 = Class.forName("A", true, c2);
Class<?> classeB_c2 = Class.forName("B", true, c2);

executerMain(classeA_c1,args);
executerMain(classeA_c2,args);

if(classeA_c1!=classeA_c2)
   System.out.println("les deux classes A chargées sont bien différentes");
Thread.currentThread().setContextClassLoader(c2);
// exécution de la méthode main de la classe B, 
à compléter

Trace d'exécution attendue

bloc de A
bloc de A
bloc de B
A : a b c
A : a b c
les deux classes A chargées sont bien différentes
B : a b c

Attention, vous ne devez avoir qu'une seule fois la ligne bloc de B sur votre écran (exécution du bloc statique est faite lors du chargement dans c2)