Je sais que cela peut être une question idiote pour les codeurs expérimentés. Mais j'ai une bibliothèque (un client http) dont certains des autres frameworks / jars utilisés dans mon projet ont besoin. Mais tous nécessitent différentes versions majeures telles que:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
Le chargeur de classe est-il assez intelligent pour les séparer d'une manière ou d'une autre? Préférablement pas? Comment le Classloader gère-t-il cela, au cas où une classe serait la même dans les trois fichiers JAR. Lequel est chargé et pourquoi?
Le Classloader ne récupère-t-il qu'un seul bocal ou mélange-t-il les classes de manière arbitraire? Par exemple, si une classe est chargée depuis la version 1.jar, toutes les autres classes chargées depuis le même chargeur de classe iront toutes dans le même fichier jar?
Comment gérez-vous ce problème?
Y a-t-il une astuce pour "incorporer" les fichiers jar dans le fichier "required.jar" afin que les soient considérés comme "une unité / paquet" par le Classloader
, ou liés d'une manière ou d'une autre?
la source
Chaque charge de classe sélectionne exactement une classe. Habituellement le premier trouvé.
OSGi vise à résoudre le problème de plusieurs versions d'un même fichier jar. Equinox et Apache Felix sont les implémentations open source courantes pour OSGi.
la source
Classloader chargera les classes à partir du fichier jar qui se trouvait en premier dans le chemin de classe. Normalement, les versions incompatibles de la bibliothèque auront des différences dans les packages, mais dans le cas peu probable, elles sont vraiment incompatibles et ne peuvent pas être remplacées par une seule - essayez jarjar.
la source
Les chargeurs de classe chargent la classe à la demande. Cela signifie que la classe requise en premier par votre application et les bibliothèques associées seraient chargées avant les autres classes; la demande de chargement des classes dépendantes est généralement émise pendant le processus de chargement et de liaison d'une classe dépendante.
Vous êtes susceptible de rencontrer des
LinkageError
affirmations indiquant que des définitions de classe en double ont été rencontrées pour les chargeurs de classe n'essaient généralement pas de déterminer quelle classe doit être chargée en premier (s'il y a deux classes ou plus du même nom présentes dans le chemin de classe du chargeur). Parfois, le chargeur de classe chargera la première classe apparaissant dans le chemin de classe et ignorera les classes en double, mais cela dépend de l'implémentation du chargeur.La pratique recommandée pour résoudre ce type d'erreurs consiste à utiliser un chargeur de classe distinct pour chaque ensemble de bibliothèques ayant 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 seront chargées par le même chargeur de classe qui n'a pas accès aux autres bibliothèques et dépendances.
la source
Vous pouvez utiliser
URLClassLoader
for require pour charger les classes à partir d'une version diff-2 de jars:la source