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 :

Utilisation de classloader pour cloisoner du code


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de Mobius
    Profil pro
    none
    Inscrit en
    Avril 2005
    Messages
    463
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : none

    Informations forums :
    Inscription : Avril 2005
    Messages : 463
    Par défaut Utilisation de classloader pour cloisoner du code
    Afin de réaliser des tests unitaire sur du code qui peut être cloisonné (par exemple dans un contexte J2EE), je cherche à créer un espèce de "mini container" permettant d'isoler du code, ou de charger deux fois la même classe dans deux classloader différent (afin de reproduire un environnement similaire pour un test unitaire).
    Voici un embryon de code :
    Code Java : 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
    import java.net.URL;
    import java.net.URLClassLoader;
     
    public class Main {
        public static class MiniContainer {
    	static {
    	    System.out.println("loaded");
    	}
     
    	public void run() {
    	}
        }
     
        public static void main(String[] args) throws Exception {
    	URL[] urls = new URL[] {
    		ClassLoader.getSystemResource("."),
    		ClassLoader.getSystemResource(MiniContainer.class.getName()
    			.replace('.', '/') + ".class")
     
    	};
    	URLClassLoader cl1 = new URLClassLoader(urls);
    	URLClassLoader cl2 = new URLClassLoader(urls);
    	Class<?> class1 = cl1.loadClass(MiniContainer.class.getName());
    	Class<?> class2 = cl2.loadClass(MiniContainer.class.getName());
    	System.out.println(class1 == class2);
    	MiniContainer c1 = (MiniContainer) class1.newInstance();
    	MiniContainer c2 = (MiniContainer) class2.newInstance();
        }
    }
    Le problème c'est que les deux classes chargé sont les mêmes alors qu'elles sont chargées par deux classloaders différents. La classe n'est même chargé qu'une seule fois puisque le message "loaded" n'est affiché qu'une fois.

    Dans ce cas, comment arriver à charger deux fois la même classe dans deux classloaders différents ?

    Dernière remarque dans le code données en exemple, j'aimerai que les deux dernières ligne provoque une ClassCastException.

    Merci d'avance.

  2. #2
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Pour commencer l'URL du classloader doit référencer le répertoire de base et non pas le fichier *.class. Et attention à ClassLoader.getSystemResource("."); qui ne retourne pas forcément le on chemin selon le contexte...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    URL[] urls = new URL[] {
    	MiniContainer.class.getProtectionDomain().getCodeSource().getLocation()
    };

    Enfin ton problème vient du fait que les 2 classloaders ne sont pas indépendant : ils sont lié au classloader système qui s'occupe de charger la classe. Il faut les créer sans "parent" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	URLClassLoader cl1 = new URLClassLoader(urls, null);
    	URLClassLoader cl2 = new URLClassLoader(urls, null);

    Enfin le cast sur tes dernières lignes est invalides (la classe MiniContainer du classloader de base n'est pas "la même" que celle de tes classloader personnalisés).


    a++

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    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 482
    Par défaut
    même sans parent, en test unitaire, ca risque de ne pas marcher suivant comment les test sont lancés. Parfois, les classes du projet se retrouvent chargées par le classloader système (bootstrap), et non pas par un classloader intermédiare. De plus, J2EE ne respecte pas le modèle de délagation des classloader, donc tu devrais fournir un classloader qui ne le fait pas non plus (fait un recherch d'abord dans son classloader puis seulement dans le parent et pas l'inverse)

  4. #4
    Membre chevronné Avatar de Mobius
    Profil pro
    none
    Inscrit en
    Avril 2005
    Messages
    463
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : none

    Informations forums :
    Inscription : Avril 2005
    Messages : 463
    Par défaut
    Merci a tous les deux pour ces précisions.
    Avec vos conseils j'ai enfin réussis a faire ce que voulais à peu près proprement.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/07/2009, 11h40
  2. peut-on utiliser les CLR pour appeler du code Java ?
    Par Mathusalem dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 16/09/2008, 13h42
  3. Réponses: 1
    Dernier message: 17/04/2007, 13h07

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