Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
839 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  Problème de ClassLoader

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème de ClassLoader

n°685184
leonhard
Posté le 26-03-2004 à 16:43:52  profilanswer
 

Salut les gens !
 
J'ai un petit prob avec un class loader artisanal... Quand je lance le programme ci-dessous, le class loader dit qu'il peut instancier la classe (j'ai même mis un log dans le constructeur)... par contre, sitôt que j'essaie d'utiliser l'objet créé... paf NoClassDefFoundError
 
Valà le prog main :

Code :
  1. public static void main (String args[])
  2.     {
  3. TestCustomURLClassLoader tcl = new    TestURLClassLoader();
  4. CustomURLClassLoader customCL = new CustomURLClassLoader();
  5. try {
  6.     Class dummy = customCL.loadClass("javasec.classload.DummyClass", true);
  7.     System.out.println ("Class dummyCL : " + dummy.getName());
  8.     System.out.println ("dummy: class loader : " + dummy.getClassLoader().toString());
  9.     Object object = dummy.newInstance();
  10.           // l'erreur apparait seulement si je met cette ligne...
  11.     System.out.println("Dummy object value : " + ((DummyClass)object).getValue());
  12. } catch (Exception e1) {
  13.     e1.printStackTrace();
  14. }
  15.     }
  16. }


 
Alors si qqun à une idée qu'il veut absolument me faire partager, surtout pas de gêne entre nous  :)  
 
Ah encore une remarque... bien entendu, la classe DummyClass n'est pas dans le classpath, sinon elle n'est pas chargé par mon class loader, mais par le class loader de base... et c'est nettement moins intéressant...
 
Je ne sais si l'output de ce programme à de l'intérêt, mais au cas ou :

Code :
  1. CustomURLClassLoader constructor
  2. url[0] : http://localhost:8000/
  3. url[1] : file:/home/azubi/AJClasses/
  4. CustomURLClassLoader::loadClass() javasec.classload.DummyClass
  5. CustomURLClassLoader::findClass()javasec.classload.DummyClass
  6. CustomURLClassLoader::getPermissions()
  7. CustomURLClassLoader::loadClass() java.lang.Object
  8. Class dummyCL : javasec.classload.DummyClass
  9. Exception in thread "main" java.lang.NoClassDefFoundError: javasec/classload/DummyClass
  10. dummy: class loader : javasec.classload.CustomURLClassLoader@1034bb5
  11. CustomURLClassLoader::loadClass() java.lang.System
  12.         at javasec.classload.TestCustomURLClassLoader.main(Unknown Source)
  13. CustomURLClassLoader::loadClass() java.io.PrintStream
  14. DummyClass::constructor...
  15. CustomURLClassLoader::loadClass() java.lang.StringBuffer
  16. DummyClass::constructor ok!7
  17. Java Result: 1


Message édité par leonhard le 26-03-2004 à 16:50:43
mood
Publicité
Posté le 26-03-2004 à 16:43:52  profilanswer
 

n°685209
loozerz
Posté le 26-03-2004 à 17:13:01  profilanswer
 


A vue de nez c'est un probleme de relations entre classLoaders. Il faut savoir qu'en Java, une classe est associee a un classLoader qui definit un espace de nom. Par exemple, tu peux avoir 2 classes Toto dans la meme VM, une chargee par un CL (disons A) et une autre par un CL B. Du point de vue de la VM, ce seront 2 classes differentes. Pour remedier a ca, il y a la notion de classLoader parent.  
 
Ton probleme est probablement  celui la. Plus exactement, la classe Dummy a ete chargee par customCL. Mais la classe de ton programme a ete chargee par le CL "standard" (SecureClassLoader). Or si ton customCL n'a pas ete construit comme fils du CL standard ET n'a pas demande au CL standard de charger lui aussi la classe Dummy, tu ne peux pas les voir.  
 
Un petit schema pour expliquer (le premier class loader est le CL primordial, tu n'y a pas acces, c'est celui qui chargent les classes java de base et qui charge les autres CLs)
 
         CL Primordial
         /
        /
    SecureClassLoader
       |
       |
    URLClassLoader  
       |
       |
    CustomURLClassLoader
 
Tu dois avoir cette situation si tu veux que ca marche, mais ce n'est pas suffisant. Il faut que lorsque ton CustomURLClassLoader charge la classe, il demande a son parent de la charger pour lui.  
 
Y'a pas de solution miracle, ca depend vraiment de ce que tu veux faire. Pour t'aider a debugger, tu peux demander a voir le CL utilise pour charger une classe:
 
 

Code :
  1. System.out.println(object.getClass().getClassLoader());


 
Ca te permettra de voir qui charge quoi.
 
Pour te donner un exemple, dans le Java de Sun, l'URLClassLoader ne charge pas de classe, il ne fait que trouver ou elle se trouve. Ensuite, il appelle loadClass de son parent, le SecureClassLoader.
 
Looz

n°685218
leonhard
Posté le 26-03-2004 à 17:19:59  profilanswer
 

loozerz a écrit :


...
Ton probleme est probablement  celui la. Plus exactement, la classe Dummy a ete chargee par customCL. Mais la classe de ton programme a ete chargee par le CL "standard" (SecureClassLoader). Or si ton customCL n'a pas ete construit comme fils du CL standard ET n'a pas demande au CL standard de charger lui aussi la classe Dummy, tu ne peux pas les voir.  
 
...
 


 
ben justement ma classe Dummy est bien chargée par mon class loader.. mais je vais encore lire attentivement ce que tu as écrit pour essayer de comprendre ou j'ai merdé... Parce que je voudrais vraiment que ma classe soit chargée par mon class loader et pas par le class loader qui charge les classes du classpath et qui a donc chargé mon programm main...
 
merci de ton aide

n°685247
loozerz
Posté le 26-03-2004 à 17:47:05  profilanswer
 

Si tu fais charger ta class dummy uniquement par ton CL, les classes chargees par d'autres CL ne la verront pas. C'est une securite de Java.  
 
Looz.

n°685371
benou
Posté le 26-03-2004 à 20:31:26  profilanswer
 

ben déjà je suis étonné que ton programme s'execute jusque là vu que tu as une référence en dur dans la classe main à la classe "DummyClass" (dans le cast) => au chargement de la calsse main, le classloader system va essayer de charger la DummyClass et donc ca devrait planter puisque tu précises qu'elle n'est pas accessible dans le classpath

n°685377
leonhard
Posté le 26-03-2004 à 21:01:03  profilanswer
 

benou a écrit :

ben déjà je suis étonné que ton programme s'execute jusque là vu que tu as une référence en dur dans la classe main à la classe "DummyClass" (dans le cast) => au chargement de la calsse main, le classloader system va essayer de charger la DummyClass et donc ca devrait planter puisque tu précises qu'elle n'est pas accessible dans le classpath


 
ben mon class loader perso est une sous-classe de URLClassLoader. Donc en donnant le bon url au constructeur du class loader, il la trouve... En plus en mettant des traces diverses, je vois :
1) mon class loader essaye de déléguer le chargement de la classe DummyClass à son parent... et comme ça ne marche pas, il la charge lui-même...
 
2)Le class loader parent de mon class loader est le class loader qui a chargé le programme main (Launcher$AppClassLoader@92e78c) même classe, même instance...
 
3) si je crée l'instance de DummyClass avec un newInstance(), il crée bien l'objet (le constructeur no-args est bien appellé sans erreur), mais ensuite y'a NoClassDefFoundError si j'essaie d'accéder à une méthode ou à un argument de cet objet...  
 
Je pensais que c'était un problème de codebase ou qq chose comme ça (genre annotation de la classe), mais je n'ai encore rien trouvé... je ne désespère pas d'y arriver cependant.
 
merci pour votre aide et bonne soirée

n°685409
benou
Posté le 26-03-2004 à 22:09:39  profilanswer
 

t'as pas répondu à mon intérogation ... tu trouves pas bizarre de faire une référence statique à une classe sensée ne pas être disponible par le classloader par défaut ??
 
Essaye de faire la même chose en invoquant la méthode getValue dynamiquement...

n°685421
leonhard
Posté le 26-03-2004 à 22:41:20  profilanswer
 

benou a écrit :

t'as pas répondu à mon intérogation ... tu trouves pas bizarre de faire une référence statique à une classe sensée ne pas être disponible par le classloader par défaut ??
 
Essaye de faire la même chose en invoquant la méthode getValue dynamiquement...


 
t'as raison, mais je ne comprends pas très bien ce que tu entends par "appeller la méthode getValue() dynamiquement". Est-ce que je dois utiliser l'introspection pour appeller cette méthode par un invoke ? autrement je vois pas trop comment faire... comment caster un la variable Object en DummyClass sans le faire statiquement ... désolé, je suis un petit peu lent à la détente

n°685422
benou
Posté le 26-03-2004 à 22:54:14  profilanswer
 

leonhard a écrit :


Est-ce que je dois utiliser l'introspection pour appeller cette méthode par un invoke ?  


c'est ca :jap:
 

leonhard a écrit :


comment caster un la variable Object en DummyClass sans le faire statiquement ...


ca tu peux pas ... A la rigueur, tu peux passer par une interface qui est dans le classpath et que l'objet que tu créés dynamiquement implémente...
 
mais bon, de toute façon je ne suis  pas sûr que ton problème vienne de là ... En fait, je m'attendrais à ce que ton programme plante dès le lancement parce qu'il me semble que toute les classes utilisées (statiquement) à l'intérieur d'une classe sont chargées lors du premier chargement de cette classe.
 

n°685435
leonhard
Posté le 26-03-2004 à 23:46:06  profilanswer
 

benou a écrit :


plein de choses intéressantes...


 
mais pour le moment ça marche pô... mais bon à cette heure, je commence à avoir des tdc à la place des yeux, alors merci pour ton aide et à charge de revanche (ben quoi, on peut rêver non ?)

mood
Publicité
Posté le 26-03-2004 à 23:46:06  profilanswer
 

n°685609
leonhard
Posté le 27-03-2004 à 15:32:58  profilanswer
 

leonhard a écrit :


 
mais pour le moment ça marche pô... mais bon à cette heure, je commence à avoir des tdc à la place des yeux, alors merci pour ton aide et à charge de revanche (ben quoi, on peut rêver non ?)


 
ben si ça marche... faut juste écouter les conseils de Môssieur Benou et pas écrire n'importe quoi...  
 
merci donc Môssieur Benou!

n°685824
benou
Posté le 28-03-2004 à 03:51:53  profilanswer
 

leonhard a écrit :


 
ben si ça marche... faut juste écouter les conseils de Môssieur Benou et pas écrire n'importe quoi...  
 
merci donc Môssieur Benou!


de rien :)
 
c'est avec l'invocation dynamique que ca marche c'est ca ?

n°685852
leonhard
Posté le 28-03-2004 à 12:30:08  profilanswer
 

benou a écrit :


de rien :)
 
c'est avec l'invocation dynamique que ca marche c'est ca ?


 
Yep !

n°2177210
fleure2008
Posté le 23-02-2013 à 14:47:00  profilanswer
 

je veux utiliser un jar externe à mon application et j'utilise un classloader mais je n'arrive pas à instancier la class de mon application qui utilise des packages externe dans ce jar.Merci pour votre aide


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  Problème de ClassLoader

 

Sujets relatifs
Petit probleme de div :/probleme de tableau et de font
probleme avec pointeur sur objet[C] Problème pour obtenir l'@ IP
Probleme htmlUn probleme avec unserialize( )
Problème pour signer une applet : pb avec jarsignerprobleme avec la couleur de fond d'un DIV...
Probleme avec cette merd... de easy php/ myadminprobleme avec iostream.h dans visual.net
Plus de sujets relatifs à : Problème de ClassLoader


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR