Почему JAR работает правильно, когда помещается внутри библиотек WAR, но не внутри общих библиотек tomcat?

У меня есть приложение (WAR), развернутое на Tomcat, содержащее несколько файлов jar. По причинам, мне нужно расширить класс внутри одного из этих jar-файлов и переопределить один из его методов. Новый метод будет отличаться для каждого клиента в зависимости от его потребностей.

Что я сделал, так это создал небольшой файл jar, который зависит от основного jar, добавил класс, расширяющий исходный, и скомпилировал его.

Теперь я хочу развернуть его на Tomcat, чтобы новый класс загружался с помощью Spring. Это нормально работает, если я помещаю новую банку в WEB-INF / lib развернутой WAR, но не работает, если я помещаю ее в shared / lib (или просто lib) Tomcat. Ошибка - это ClassNotFoundException для того, который я расширяю (в основном каждый класс, который исходит из основного jar, не может быть найден). Я уже проверил catalina.properties, и он правильно загружает .jar в обоих местах.

У меня вопрос: почему этот JAR работает только в том случае, если я помещаю его в библиотеки WAR, но не в том случае, если я помещаю его в общую библиотеку Tomcat? Версия Tomcat - 7.0.86

Небольшая схема, чтобы лучше понять, что работает, а что нет:

    - tomcat folder
      - lib
        - jar-that-extends-main-jar.jar (ClassNotFoundException for the one I'm extending)
      - shared
        - lib
          - jar-that-extends-main-jar.jar (ClassNotFoundException for the one I'm extending)
      - webapps
        - my-application
          - WEB/INF
            - lib
              - jar-that-extends-main-jar.jar (this works correctly and I can use my custom class)
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Tomcat использует различные загрузчики классов в виде древовидной иерархии (здесь вы можете увидеть картинку и некоторые пояснения: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html).

По сути, у вас есть загрузчик классов для каждого веб-приложения, один для общих библиотек, один для системы и один для начальной загрузки, где загрузчики классов веб-приложений находятся в нижней части дерева, а затем идут вверх. Однако загрузчик классов может получить доступ только к своим родительским загрузчикам классов, но не наоборот, поэтому при поиске класса загрузчик классов будет смотреть на свои собственные классы, а затем запрашивать родительские загрузчики классов для этого конкретного класса.

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

Хорошо, спасибо за объяснение, поскольку библиотека, размещенная внутри общих библиотек tomcat, должна использоваться для всех различных развернутых веб-приложений, я думаю, было бы странно, что ей нужна зависимость одного из этих

Redemin 08.04.2021 12:10

@Redemin: обратите внимание, что иерархия загрузчика классов Tomcat не означает, что вам нужно физически разместить свой JAR в WEB-INF/lib. Это также можно сделать с помощью конфигурация контекста, оставив JAR во внешнем расположении. Tomcat 7 имел аналогичная функция.

Piotr P. Karwasz 08.04.2021 12:29

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