У меня есть приложение (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)




Tomcat использует различные загрузчики классов в виде древовидной иерархии (здесь вы можете увидеть картинку и некоторые пояснения: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html).
По сути, у вас есть загрузчик классов для каждого веб-приложения, один для общих библиотек, один для системы и один для начальной загрузки, где загрузчики классов веб-приложений находятся в нижней части дерева, а затем идут вверх. Однако загрузчик классов может получить доступ только к своим родительским загрузчикам классов, но не наоборот, поэтому при поиске класса загрузчик классов будет смотреть на свои собственные классы, а затем запрашивать родительские загрузчики классов для этого конкретного класса.
Вот почему вы можете получить доступ к классам в общем загрузчике классов из своего веб-приложения, но не наоборот.
@Redemin: обратите внимание, что иерархия загрузчика классов Tomcat не означает, что вам нужно физически разместить свой JAR в WEB-INF/lib. Это также можно сделать с помощью конфигурация контекста, оставив JAR во внешнем расположении. Tomcat 7 имел аналогичная функция.
Хорошо, спасибо за объяснение, поскольку библиотека, размещенная внутри общих библиотек tomcat, должна использоваться для всех различных развернутых веб-приложений, я думаю, было бы странно, что ей нужна зависимость одного из этих