且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Tomcat类加载器违反了委派策略

更新时间:2023-02-16 12:00:11

此行为是故意的,它使您可以在每个WAR中独立地覆盖Tomcat本身提供的库。例如,您可以为部署到容器的每个应用程序覆盖具有不同版本的Log4J,而不会引起任何问题或破坏其他应用程序。从Tomcat 文档

This behavior is intentional and it allows you to override libraries provided in the Tomcat itself independently in every WAR. For instance you can override Log4J with different version per each application deployed to the container without introducing any issues or breaking other applications. From Tomcat documentation:


与许多服务器应用程序一样,Tomcat安装了各种类加载器,以允许容器的不同部分,以及在容器,以访问不同的可用类和资源存储库。此机制用于提供Servlet规范2.4版中定义的功能-特别是9.4和9.6节。

Like many server applications, Tomcat installs a variety of class loaders [...] to allow different portions of the container, and the web applications running on the container, to have access to different repositories of available classes and resources. This mechanism is used to provide the functionality defined in the Servlet Specification, version 2.4 — in particular, Sections 9.4 and 9.6.

违反常规的委派算法,但这也是其他应用程序服务器的工作方式(例如JBoss)。

It does violate the normal delegation algorithm, but this is how other application server work as well (JBoss for instance).

Ad。问题2 :是的,这很危险,您必须记住有关同步的信息,并且无法控制谁修改了此变量。我会完全避免使用 static 字段。

Ad. question 2: Yes, it is dangerous, you have to remember about synchronization and have no control over who modifies this variable. I would avoid static fields altogether.

例如 EhCache 允许您共享 CacheManager 。这是通过 net.sf.ehcache.CacheManager#singleton static volatile 字段实现的。现在您遇到了各种各样的问题:如果将 ehcache.jar 放入Tomcat的 / lib 中,它将按预期工作。但是,如果每个Web应用程序都有自己的JAR文件副本,则共享将无法进行,因为每个Web应用程序都有其自己的 CacheManager 类副本。当只有一个应用程序具有自己的 ehcache.jar 时,情况就更糟了-所有应用程序将共享 CachedManager 的相同实例除了将 ehcache.jar 打包在一起的那个。很难找到这样的错误...

For instance EhCache allows you to share CacheManager. This is implemented via net.sf.ehcache.CacheManager#singleton static volatile field. Now you get all sort of problems: if you put ehcache.jar in Tomcat's /lib, it will work as expected. However if each web application has its own copy of the JAR file, sharing will not work because each web app has its own copy of CacheManager class. It gets even worse when only one application has its own ehcache.jar - all applications will share the same instance of CachedManager except the one having ehcache.jar packaged together. Such error are very hard to track down...