Tomcat 类加载器违反委托策略
问题1: 众所周知,当类加载器要加载一个类时,它会将请求委托给其父类加载器。但是在 Tomcat 中,情况并非如此:您可以加载类来覆盖放在公共 lib 目录中的同名类。这意味着 Tomcat
WebappClassloader
不遵循委托策略。是否违反约定?问题2: 我编写了一个类并将其放在公共 lib 目录中,显然该类在网络应用程序之间共享。例如,每个 Web 应用程序都可以读取/写入类的静态字段。此外,JDK中的类由Bootstrap类加载器加载,然后它们的静态字段被任何Web应用程序共享,这危险吗?
Question1:
As we know, when a classloader is about to load a class, it delegates the request to its parent classloader. However in Tomcat, it doesn’t: you could load your class to overwrite the same name class which is put in common lib directory. This means TomcatWebappClassloader
doesn’t follow delegating policy. Is it violation of convention?Question2:
I wrote a class and put it in common lib directory, obviously the class is shared among web apps. For instance, every web app can read/write the static field of the class. Further, classes in JDK are loaded by Bootstrap classloader, then their static fields are shared by any web apps, is it dangerous?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这种行为是有意为之的,它允许您在每个 WAR 中独立地覆盖 Tomcat 本身提供的库。例如,您可以使用部署到容器的每个应用程序的不同版本覆盖 Log4J,而不会引入任何问题或破坏其他应用程序。来自 Tomcat 文档:
它确实违反了正常的委托算法,但这也是其他应用程序服务器的工作方式(例如 JBoss)。
广告。问题2:是的,这很危险,你必须记住同步并且无法控制谁修改这个变量。我会完全避免
static
字段。例如 EhCache 允许您共享
CacheManager
。这是通过net.sf.ehcache.CacheManager#singleton
static volatile
字段实现的。现在您遇到了各种各样的问题:如果您将ehcache.jar
放入 Tomcat 的/lib
中,它将按预期工作。但是,如果每个 Web 应用程序都有自己的 JAR 文件副本,则共享将不起作用,因为每个 Web 应用程序都有自己的CacheManager
类副本。当只有一个应用程序拥有自己的ehcache.jar
时,情况会变得更糟 - 所有应用程序都将共享同一个CachedManager
实例,除了拥有ehcache.jar
的应用程序之外code> 打包在一起。这样的错误很难追踪......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:
It does violate the normal delegation algorithm, but this is how other application server work as well (JBoss for instance).
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.For instance EhCache allows you to share
CacheManager
. This is implemented vianet.sf.ehcache.CacheManager#singleton
static volatile
field. Now you get all sort of problems: if you putehcache.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 ofCacheManager
class. It gets even worse when only one application has its ownehcache.jar
- all applications will share the same instance ofCachedManager
except the one havingehcache.jar
packaged together. Such error are very hard to track down...