Загрузчик классов Tomcat нарушает политику делегирования - PullRequest
4 голосов
/ 09 сентября 2011
  • Question1: Как мы знаем, когда загрузчик классов собирается загрузить класс, он делегирует запрос своему родительскому загрузчику классов. Однако в Tomcat это не так: вы можете загрузить свой класс, чтобы перезаписать тот же класс имен, который помещен в общий каталог lib. Это означает, что Tomcat WebappClassloader не следует политике делегирования. Это нарушение конвенции?

  • Вопрос2: Я написал класс и поместил его в общую директорию lib, очевидно, этот класс является общим для веб-приложений. Например, каждое веб-приложение может читать / записывать статическое поле класса. Кроме того, классы в JDK загружаются загрузчиком классов Bootstrap, затем их статические поля используются всеми веб-приложениями, это опасно?

1 Ответ

6 голосов
/ 09 сентября 2011

Это поведение является преднамеренным, и оно позволяет вам переопределять библиотеки, предоставляемые в самом Tomcat, независимо в каждой WAR.Например, вы можете переопределить Log4J с разными версиями для каждого приложения, развернутого в контейнере, не создавая проблем и не нарушая другие приложения.Из документации Tomcat :

Как и многие серверные приложения, Tomcat устанавливает различные загрузчики классов [...] до , позволяющие использовать различные части контейнера и вебприложения, работающие на контейнере , до имеют доступ к различным репозиториям доступных классов и ресурсов .Этот механизм используется для обеспечения функциональности, определенной в спецификации сервлета, версия 2.4, в частности, в разделах 9.4 и 9.6.

Он нарушает алгоритм обычного делегирования, но так работает другой сервер приложений.также (например, JBoss).

Ad.вопрос 2 : Да, это опасно, вы должны помнить о синхронизации и не иметь никакого контроля над тем, кто изменяет эту переменную.Я бы вообще не использовал static полей.

Например, EhCache позволяет вам поделиться CacheManager.Это осуществляется через поле net.sf.ehcache.CacheManager#singleton static volatile.Теперь вы получаете все виды проблем: если вы введете ehcache.jar в Tomcat /lib, он будет работать как положено.Однако, если у каждого веб-приложения есть своя собственная копия файла JAR, совместное использование не будет работать, поскольку у каждого веб-приложения есть своя собственная копия класса CacheManager.Еще хуже, когда только одно приложение имеет свой собственный ehcache.jar - все приложения будут использовать один и тот же экземпляр CachedManager, за исключением одного, в котором ehcache.jar упакованы вместе.Такую ошибку очень трудно отследить ...

...