Bonjour,
Mon objectif est de charger et lister les classes contenues dans un fichier jar, puis parmi elles trouver celles qui implémentent certaines interfaces spécifiques.
Je vais probablement finir par utiliser un URLClassLoader puisqu'il fait la partie principale du boulot, mais je voudrais vraiment comprendre d'où vient mon problême, juste pour ma culture Java
En guise de référence, voilà la hierarchie de classes impliquées dans mon problème :
Commençons : j'ai implémenté mon propre ClassLoader pour charger les .class contenus dans des fichiers jar (et les lister par la même occasion), et j'ai chargé avec ce ClassLoader une classe implémentant AbstractAI.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public abstract class cero.games.uno.AbstractAI extends UnoPlayer implements AIPlayer, /* autres interfaces */ public class cero.games.uno.UnoPlayer extends PlayerBase public class cero.games.base.PlayerBase implements Player, /* autres interfaces */ public interface cero.games.AIPlayer extends Player public interface cero.games.Player
A propos de la hiérarchie des ClassLoader : le bootstrap ClassLoader a chargé seulement les classes cero.games.Player et cero.games.AIPlayer qui sont référencées par les classes utilisées dans le main.
Cependant, le reste de cero.games et cero.games.base est chargé par une instance de mon ClassLoader, celui-ci ayant le bootstrap ClassLoader comme parent.
Enfin, une autre instance de mon CL charge le package cero.games.uno, en ayant le CL précédent comme parent.
Grâce à cette hiérarchie, je respecte facilement les dépendances vers les classes contenues dans les packages supérieurs (par exemple quand cero.games.base dépend de cero.games).
Comme vous pouviez voir dans les déclarations plus haut, AIPlayer étends Player et est implémentée par AbstractAI. Cependant, quand j'utilise isAssignableFrom dans ce morceau de code, où 'c' est une classe dérivant de AbstractAI (et donc implémentant à la fois AIPlayer et Player), seul le 2eme test est vrai.
J'ai vérifié avec un débuggueur : assez logiquement, AIPlayer et Player sont tous les deux chargés par le bootstrap ClassLoader (la classe contenant ce morceau de code n'est pas chargée dynamiquement et fait référence à Player.class et AIPlayer.class, ces deux Class sont donc nécessités dès le démarrage), tandis que c a bien été chargée par mon ClassLoader personnalisé comme prévu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 if (AIPlayer.class.isAssignableFrom(c)) /* évalué faux */ aisClass.add(c.asSubclass(AIPlayer.class)); else if (Player.class.isAssignableFrom(c)) /* évalué vrai */ playerClass = c.asSubclass(Player.class);
Puisque c implémente à la fois AIPlayer et Player, je supposais qu'il serait les deux "assignableFrom" c. Mais seulement un des deux test est vrai, et c'est cela que je ne comprend pas.
Peut-être que j'ai mal compris comment isAssignableFrom marche : si vous avez un cours, je suis preneur !
Merci à vous de m'éclairer, je ne vois vraiment pas ce qui provoque ce comportement
PS : Au cas où ça puisse aider, j'utilise Eclipse 3.1
Partager