Порядок загрузки jar-файлов из каталога lib

Может ли кто-нибудь объяснить порядок загрузки jar-файлов из каталога lib в Tomcat? Это по алфавиту? Случайные? Или какой-то другой заказ?

4 ответа

Решение

Это все описано в TomLow ClassLoading HOW-TO. Это не обязательно в алфавитном порядке. Если вы наблюдали такое поведение, на него абсолютно не следует полагаться, если вы намерены поддерживать переносимость вашего веб-приложения на серверах. Например, Tomcat 6 "по совпадению" заказывает его, а Tomcat 8 - нет.

В итоге порядок загрузки выглядит следующим образом:

  1. начальная загрузка / система (JRE/lib, затем server.loader)
  2. библиотеки веб-приложений (WEB-INF/classes, затем WEB-INF/lib)
  3. общие библиотеки (common.loader, затем Tomcat/lib)
  4. библиотеки общего доступа к веб-приложениям (shared.loader)

Если вы хотите гарантировать, что JAR X будет загружен после JAR Y, вам нужно будет поместить JAR X в одно из мест, которое появится позже в приведенном выше листинге.

Однако есть исключения, которые упоминаются в документации по tomcat.

Наконец, загрузчик классов веб-приложений всегда сначала делегирует классы API JavaEE для спецификаций, реализованных Tomcat (Servlet, JSP, EL, WebSocket). Все остальные загрузчики классов в Tomcat следуют обычному шаблону делегирования.

Это означает, что если веб-приложение содержит какие-либо классы JavaEE (javax.*), то он будет игнорироваться котом.

Для каждого загрузчика классы просто загружаются JVM в том порядке, в котором они должны быть импортированы / выполнены и еще не загружены.

На самом деле, это в алфавитном порядке! (Внутри определенного каталога, например, каталога 'lib', который упоминает оригинальный автор.)

Более конкретно, если вы посмотрите на источник для Tomcat 6, в классе FileDirContext, метод list() звонки Arrays.sort() на массиве имен файлов jar, которые найдены.

Я также проверил это вручную. Я создаю войну с JSP, который призывает HelloWorld.getGreeting()и поместите две почти идентичные банки, содержащие немного разные версии HelloWorld в каталог WEB-INF/lib. Один говорит "Привет, мир", другой - "До свидания, жестокий мир".

Если я назову версию "Hello, world" a.jar, а версию "goodbye" b.jar и перезапущу Tomcat, я получу текст "Hello". Если я назову банки в обратном порядке и перезапущу Tomcat, я получу текст "До свидания".

Насколько я смог определить, это поведение НЕ задокументировано, НЕ указано и на него НЕ следует полагаться. Но это по алфавиту - пока.

Заказ на загруженные банки в папке WEb-INF/lib.

Для кота 5-7 порядок в алфавитном порядке. Он использует сортировку.

Для tomcat 8 случайное решение определяется базовой файловой системой.

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

Я полностью согласен с ответом, предоставленным BalusC. Единственное, что нужно добавить, это то, что когда загружается JAR из соответствующего загрузчика классов, он проверяет алфавитный порядок.

У меня была ситуация для загрузки "XSSFWorkbook" в мое веб-приложение для чтения данных из таблицы Excel, и у меня было два JARS "poi-ooxml-3.9.jar" и "org.eclipse.birt.runtime_4.3.1.v20130918-1142.jar" с тем же именем класса и структурой пакета. Я просто восстановил позже, так что в алфавитном порядке идет рядом с более ранним, и это помогло мне. Просто хотел поделиться тем же.

Удачи

В нашей среде WebSphere разные машины загружают банку в разном порядке. Поэтому я согласен с user2193008. Мы сталкиваемся с проблемой загрузчика классов в производственной среде, где тот же код отлично работает в более низкой среде. Мы исправили проблему, удалив дубликат jar в lib, например, есть две версии spring jar, spring_v1.jar и spring_v2.jar, если classloader загружает сначала v1, код работает нормально, но если classloader загружает сначала v2, проблема.

Другие вопросы по тегам