42 Stimmen

Reihenfolge des Ladens von jar-Dateien aus dem lib-Verzeichnis

Kann mir jemand die Reihenfolge erklären, in der die jar-Dateien aus dem lib-Verzeichnis in Tomcat geladen werden? Ist es alphabetisch? Nach dem Zufallsprinzip? Oder eine andere Reihenfolge?

41voto

BalusC Punkte 1034465

Das alles ist beschrieben in Tomcats ClassLoading HOW-TO . Es ist nicht unbedingt in alphabetischer Reihenfolge. Wenn Sie dieses Verhalten beobachtet haben, sollte es auf keinen Fall verlassen, wenn Sie beabsichtigen, Ihre Webanwendung über mehrere Server hinweg portabel zu halten. Tomcat 6 beispielsweise bestellt es "zufällig", Tomcat 8 jedoch nicht.

Zusammengefasst lautet die Reihenfolge der Beladung wie folgt:

  1. bootstrap/system ( JRE/lib entonces server.loader )
  2. Webapp-Bibliotheken ( WEB-INF/classes entonces WEB-INF/lib )
  3. gemeinsame Bibliotheken ( common.loader entonces Tomcat/lib )
  4. gemeinsam genutzte Webapp-Bibliotheken ( shared.loader )

Wenn Sie sicherstellen möchten, dass JAR X geladen ist nach JAR Y, dann müssen Sie JAR X an einer der Stellen einfügen, an denen später in der obigen Auflistung.

Es gibt jedoch Ausnahmen, die in den folgenden Abschnitten erwähnt werden Tomcat-Dokumente

Schließlich delegiert der Klassenlader für Webanwendungen immer zuerst die JavaEE-API-Klassen für die von Tomcat implementierten Spezifikationen (Servlet, JSP, EL, WebSocket). Alle anderen Klassenlader in Tomcat folgen dem üblichen Delegationsmuster.

Das heißt, wenn eine Webanwendung JavaEE-Klassen enthält ( javax.* ), dann wird er vom Tomcat ignoriert.

Für jeden Lader werden die Klassen von der JVM nur in der Reihenfolge geladen, in der sie importiert/ausgeführt werden müssen und noch nicht geladen sind.

36voto

Charles Roth Punkte 369

Eigentlich ist es es in alphabetischer Reihenfolge! (Innerhalb eines bestimmten Verzeichnisses, z. B. des Verzeichnisses "lib", das der ursprüngliche Poster erwähnt hat).

Genauer gesagt, wenn Sie sich den Quelltext von Tomcat 6 ansehen, finden Sie in der Klasse FileDirContext die Methode list() ruft auf. Arrays.sort() auf das Array der Dateinamen der gefundenen Jars.

Ich habe dies auch manuell getestet. Ich erstelle ein War mit einem JSP, das Folgendes aufruft HelloWorld.getGreeting() und stellen zwei fast identische Gläser mit leicht unterschiedlichen Versionen von HelloWorld in das Verzeichnis WEB-INF/lib. Auf dem einen steht "Hallo, Welt", auf dem anderen "Auf Wiedersehen, grausame Welt".

Wenn ich die "Hello, world"-Version a.jar und die "goodbye"-Version b.jar benenne und Tomcat neu starte, erhalte ich den "Hello"-Text. Wenn ich die Jars andersherum benenne und Tomcat neu starte, erhalte ich den Text "Goodbye".

Soweit ich feststellen konnte, ist dieses Verhalten NICHT dokumentiert, NICHT spezifiziert und man sollte sich NICHT darauf verlassen. Aber es ist alphabetisch - im Moment.

29voto

user2193008 Punkte 281

Reihenfolge der geladenen Jars im Ordner WEb-INF/lib.

Für Tomcat 5-7 ist die Reihenfolge alphabetisch. Er verwendet sort.

Bei Tomcat 8 entscheidet das zugrunde liegende Dateisystem nach dem Zufallsprinzip.

https://issues.apache.org/bugzilla/show_bug.cgi?id=57129

1voto

Ich stimme der Antwort von BalusC vollkommen zu. Der einzige Punkt, den ich hinzufügen möchte, ist, dass beim Laden eines JARs aus dem jeweiligen Classloader die alphabetische Reihenfolge überprüft wird.

Ich hatte eine Situation zu laden "XSSFWorkbook" in meiner Web-Anwendung zum Lesen von Daten aus Excel-Blatt und hatte zwei JARS "poi-ooxml-3.9.jar" und "org.eclipse.birt.runtime_4.3.1.v20130918-1142.jar" mit gleichen Klassennamen und Paketstruktur. Ich habe einfach die letztere in der alphabetischen Reihenfolge neben die frühere gestellt und das hat bei mir geklappt. Wollte nur das gleiche zu teilen.

Viel Glück

0voto

Feng Zhang Punkte 1202

In unserer WebSphere-Umgebung laden verschiedene Rechner die Jar-Dateien in unterschiedlicher Reihenfolge. Ich stimme also mit user2193008 überein. Wir haben ein Problem mit dem Klassenlader in der Produktionsumgebung, wo derselbe Code in einer niedrigeren Umgebung gut funktioniert. Wir haben das Problem behoben, indem wir ein doppeltes Jar in der Bibliothek entfernt haben. Zum Beispiel gibt es zwei Versionen von Spring-Jars, spring_v1.jar und spring_v2.jar, wenn Classloader zuerst v1 lädt, funktioniert der Code gut, aber wenn Classloader zuerst v2 lädt, gibt es Probleme.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X