126 votes

Java, Classpath, Classloading => plusieurs Versions d’un même pot/projet

Je sais que cela peut être une question stupide pour codeurs expérimentés. Mais j'ai une bibliothèque (client http) que certains des autres frameworks/pots utilisé dans mon projet l'exigent. Mais toutes nécessitent des versions majeures comme:

httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar

Est le chargeur de classe assez intelligent pour les séparer en quelque sorte? Probablement pas? Comment fonctionne le chargeur de classe gérer cela, dans le cas où une Classe est la même dans les trois pots. Qui est chargé et pourquoi?

Le chargeur de classe seulement ramassage exactement un bocal ou faut-il mélanger les classes de manière arbitraire? Ainsi par exemple, si une classe est chargée de Version-1.jar toutes les autres classes chargées à partir de la même chargeur de classe tous aller dans le même pot?

Comment gérez-vous ce problème?

Est-il une astuce pour en quelque sorte "intégrer" les bocaux dans l' "required.jar" de sorte que sont considérés comme "une unité/paquet" par l' Classloader, ou en quelque sorte liés?

61voto

Luca Putzu Points 453

Chargeur de classe les problèmes liés à une situation assez complexe. Vous devez en aucun cas tenir compte de quelques faits:

  • Les chargeurs de classe dans une application sont généralement plus qu'un seul. La classe de bootstrap loader délégués, le cas échéant. Lorsque vous instanciez une nouvelle classe la plus spécifique du chargeur de classe est appelée. S'il ne trouve pas une référence à la classe que vous tentez de charger, il délègue à son parent, et ainsi de suite, jusqu'à ce que vous obtenez à la classe de bootstrap loader. Si aucun d'entre eux de trouver une référence à la classe que vous tentez de charger, vous obtenez une ClassNotFoundException.

  • Si vous avez deux classes avec le même nom binaire, consultable par le même chargeur de classe, et que vous voulez savoir lequel d'entre eux vous chargez, vous ne pouvez inspecter la manière spécifique chargeur de classe essaie de résoudre un nom de classe.

  • Selon le langage java spécification, il n'est pas une contrainte d'unicité pour une classe de nom binaire, mais aussi loin que je peux voir, il doit être unique pour chaque chargeur de classe.

Je peux trouver un moyen de charger deux classes ayant le même nom binaire, et il s'agit de les avoir chargés (et leurs dépendances) par deux chargeurs de classes par défaut de substitution comportement. Un exemple grossier:

    ClassLoader loaderA = new MyClassLoader(libPathOne);
    ClassLoader loaderB = new MyClassLoader(libPathTwo);
    Object1 obj1 = loaderA.loadClass("first.class.binary.name", true)
    Object2 obj2 = loaderB.loadClass("second.class.binary.name", true);

J'ai toujours trouvé le chargeur de classe de personnalisation de l'une tâche délicate. Je préfère suggérer d'éviter de multiples incompatible dépendances, si possible.

21voto

Tarlog Points 5447

Chaque lancent reprend exactement une seule classe. Habituellement le premier celui trouvé.

OSGi vise à résoudre le problème de plusieurs versions du même pot. Equinox et Apache Felix sont les implémentations open source communes pour OSGi.

7voto

Alex Gitelman Points 15062

ClassLoader chargera des classes à partir du pot qui est arrivé à être le premier dans le classpath. Normalement, des versions incompatibles de bibliothèque seront ont différence en paquets, mais dans le cas peu probable où ils vraiment incompatible et ne peut pas être remplacées par one - try Victor.

6voto

Vineet Reynolds Points 40529

Les chargeurs de classe classe de charge sur demande. Cela signifie que la classe requises par votre application et ses bibliothèques d'être chargé avant d'autres classes; la demande de charger les classes dépendantes est généralement émis pendant le chargement et le processus de liaison de un en fonction de la classe.

Vous êtes susceptible de rencontrer LinkageErrors indiquant que les doublons de classe définitions ont été rencontrées pour les chargeurs de classe ne sont généralement pas tenter de déterminer à quelle classe doit être chargé en premier (si il y a deux ou plusieurs classes de même nom présent dans le classpath du chargeur). Parfois, le chargeur de classe de la charge de la première classe se produisant dans le classpath et d'ignorer les doublons de classes, mais cela dépend de la mise en œuvre de la chargeuse.

La pratique recommandée pour résoudre ce genre d'erreurs est d'utiliser un distinct du chargeur de classe pour chaque ensemble de bibliothèques qui ont des dépendances conflictuelles. De cette façon, si un chargeur de classe tente de charger des classes à partir d'une bibliothèque, les classes dépendantes serait chargé par le même chargeur de classe qui n'ont pas accès à d'autres bibliothèques et des dépendances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X