Ich weiß, dass dies für erfahrene Programmierer eine dumme Frage sein kann. Ich habe jedoch eine Bibliothek (einen http-Client), die einige der anderen in meinem Projekt verwendeten Frameworks / Jars benötigen. Aber alle erfordern unterschiedliche Hauptversionen wie:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
Ist der Klassenlader intelligent genug, um sie irgendwie zu trennen? Höchst wahrscheinlich nicht? Wie geht der Classloader damit um, falls eine Klasse in allen drei Gläsern gleich ist? Welches ist geladen und warum?
Nimmt der Classloader nur genau ein Glas auf oder mischt er Klassen willkürlich? Wenn zum Beispiel eine Klasse aus Version-1.jar geladen wird, werden alle anderen Klassen, die von demselben Klassenladeprogramm geladen werden, alle in dasselbe JAR verschoben?
Wie gehen Sie mit diesem Problem um?
Gibt es einen Trick, um die Gläser irgendwie in die "required.jar" zu "integrieren", so dass sie von der als "eine Einheit / Packung" angesehen Classloader
oder irgendwie verknüpft werden?
quelle
Jede Klassenladung wählt genau eine Klasse aus. Normalerweise wird der erste gefunden.
OSGi zielt darauf ab, das Problem mehrerer Versionen desselben Glases zu lösen. Equinox und Apache Felix sind die gängigen Open-Source-Implementierungen für OSGi.
quelle
Classloader lädt Klassen aus dem JAR, das sich zuerst im Klassenpfad befand. Normalerweise unterscheiden sich inkompatible Versionen der Bibliothek in den Paketen. In unwahrscheinlichen Fällen sind sie jedoch wirklich inkompatibel und können nicht durch ein einziges ersetzt werden - versuchen Sie es mit jarjar.
quelle
Klassenlader laden Klasse auf Anfrage. Dies bedeutet, dass die Klasse, die zuerst von Ihrer Anwendung und den zugehörigen Bibliotheken benötigt wird, vor anderen Klassen geladen wird. Die Anforderung zum Laden der abhängigen Klassen wird normalerweise während des Lade- und Verknüpfungsprozesses einer abhängigen Klasse ausgegeben.
Es ist wahrscheinlich
LinkageError
, dass Sie feststellen, dass für Klassenlader doppelte Klassendefinitionen aufgetreten sind. In der Regel wird nicht versucht, zu bestimmen, welche Klasse zuerst geladen werden soll (wenn im Klassenpfad des Loaders zwei oder mehr Klassen mit demselben Namen vorhanden sind). Manchmal lädt der Klassenladeprogramm die erste im Klassenpfad vorkommende Klasse und ignoriert die doppelten Klassen. Dies hängt jedoch von der Implementierung des Ladeprogramms ab.Die empfohlene Vorgehensweise zur Behebung solcher Fehler besteht darin, für jeden Satz von Bibliotheken mit widersprüchlichen Abhängigkeiten einen separaten Klassenladeprogramm zu verwenden. Wenn ein Klassenladeprogramm versucht, Klassen aus einer Bibliothek zu laden, werden die abhängigen Klassen auf dieselbe Weise von demselben Klassenladeprogramm geladen, das keinen Zugriff auf die anderen Bibliotheken und Abhängigkeiten hat.
quelle
Sie können die
URLClassLoader
for require verwenden, um die Klassen aus einer diff-2-Version von Jars zu laden:quelle