Tomcat 类加载器违反委托策略

发布于 2024-12-03 14:25:57 字数 313 浏览 3 评论 0原文

  • 问题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 Tomcat WebappClassloader 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

憧憬巴黎街头的黎明 2024-12-10 14:25:57

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

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

它确实违反了正常的委托算法,但这也是其他应用程序服务器的工作方式(例如 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:

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.

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 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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文