Problème de ClassLoader - Java - Programmation
Marsh Posté le 26-03-2004 à 17:13:01
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 :
|
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
Marsh Posté le 26-03-2004 à 17:19:59
loozerz a écrit : |
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
Marsh Posté le 26-03-2004 à 17:47:05
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.
Marsh Posté le 26-03-2004 à 20:31:26
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
Marsh Posté le 26-03-2004 à 21:01:03
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
Marsh Posté le 26-03-2004 à 22:09:39
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...
Marsh Posté le 26-03-2004 à 22:41:20
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 ?? |
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
Marsh Posté le 26-03-2004 à 22:54:14
leonhard a écrit : |
c'est ca
leonhard a écrit : |
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.
Marsh Posté le 26-03-2004 à 23:46:06
benou 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 ?)
Marsh Posté le 27-03-2004 à 15:32:58
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!
Marsh Posté le 28-03-2004 à 03:51:53
leonhard a écrit : |
de rien
c'est avec l'invocation dynamique que ca marche c'est ca ?
Marsh Posté le 28-03-2004 à 12:30:08
ReplyMarsh Posté le 23-02-2013 à 14:47:00
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
Marsh Posté le 26-03-2004 à 16:43:52
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 :
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 :
Message édité par leonhard le 26-03-2004 à 16:50:43