Может ли кто-нибудь объяснить порядок, в котором файлы jar загружаются из каталога lib в Tomcat? Это по алфавиту? Случайные? Или какой-то другой порядок?
Порядок загрузки файлов jar из каталога lib
Ответ 1
Все описано в Tomcat ClassLoading HOW-TO. Это не обязательно в алфавитном порядке. Если вы заметили это поведение, на него следует полагаться абсолютно не, если вы намереваетесь поддерживать перенос веб-сервера на разных серверах. Например, Tomcat 6 "по совпадению" заказывает его, но Tomcat 8 не делает.
Подводя итог, порядок загрузки выглядит следующим образом:
- bootstrap/system (
JRE/lib
, затемserver.loader
) - библиотеки webapp (
WEB-INF/classes
, затемWEB-INF/lib
) - общие библиотеки (
common.loader
, затемTomcat/lib
) - webapp-shared libraries (
shared.loader
)
Если вы хотите гарантировать загрузку JAR X после JAR Y, вам нужно будет поместить JAR X в одно из мест, которое появится позже в списке выше.
Существуют исключения, которые упоминаются в doccat docs
Наконец, загрузчик классов веб-приложений всегда будет делегировать сначала классы JavaEE API для спецификаций, реализованных Tomcat (Servlet, JSP, EL, WebSocket). Все другие загрузчики классов в Tomcat следуют обычному шаблону делегирования.
Это означает, что если webapp содержит любые классы JavaEE (javax.*
), то он будет игнорироваться tomcat.
Для каждого загрузчика классы просто загружаются JVM в порядке, когда они должны быть импортированы/выполнены и еще не загружены.
Ответ 2
Собственно, это в алфавитном порядке! (В пределах определенного каталога, например, каталога "lib", который упоминается в оригинальном плакате.)
Более конкретно, если вы посмотрите на источник Tomcat 6, в классе FileDirContext
, метод list()
вызывает Arrays.sort()
в массиве имен файлов найденных банок.
Я тоже проверил это вручную. Я создаю войну с JSP, который вызывает HelloWorld.getGreeting()
, и помещаю два почти идентичных банка, содержащих несколько разные версии HelloWorld
в каталог WEB-INF/lib. Один говорит "Привет, мир", другой "До свидания, жестокий мир".
Если я называю "Hello, world" версию a.jar и "прощаю" версию b.jar и перезагружаю Tomcat, я получаю текст "Hello". Если я назову баночки другим способом и перезапустил Tomcat, я получаю текст "Прощай".
Насколько я смог определить, это поведение НЕ документировано, НЕ указано, и на него не следует полагаться. Но это в алфавитном порядке - пока.
Ответ 3
Заказать загруженные банки в папке WEb-INF/lib.
Для tomcat 5-7 порядок в алфавитном порядке. Он использует сортировку.
Для tomcat 8 случайным образом определяется базовая файловая система.
Ответ 4
Я полностью согласен с ответом, предоставленным BalusC. Только указать, что нужно добавить, когда дело доходит до загрузки JAR из соответствующего загрузчика классов, он проверяет алфавитный порядок.
У меня была ситуация, когда я загружал "XSSFWorkbook" в своем веб-приложении для чтения данных с листа excel и имел два JARS "poi-ooxml-3.9.jar" и "org.eclipse.birt.runtime_4.3.1.v20130918-1142.jar" с тем же именем класса и структурой пакета. Я просто перестал позже, поэтому в своем алфавитном порядке рядом с предыдущим, и это сделало трюк для меня. Просто хотел поделиться тем же.
Удача