【问题标题】:Tomcat classloader violates delegating policyTomcat 类加载器违反委派策略
【发布时间】:2011-09-09 07:58:33
【问题描述】:
  • 问题 1: 众所周知,当一个类加载器要加载一个类时,它会将请求委托给它的父类加载器。但是在 Tomcat 中,它不会:您可以加载您的类以覆盖放在公共 lib 目录中的同名类。这意味着 Tomcat WebappClassloader 不遵循委派策略。是否违反约定?

  • 问题 2: 我写了一个类并将其放在 common lib 目录中,显然该类是在 web 应用程序之间共享的。例如,每个 Web 应用程序都可以读取/写入类的静态字段。另外,JDK中的类是通过Bootstrap类加载器加载的,然后它们的静态字段被任何Web应用程序共享,这很危险吗?

【问题讨论】:

    标签: java tomcat classloader


    【解决方案1】:

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

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

    它确实违反了正常的委托算法,但其他应用服务器也是这样工作的(例如 JBoss)。

    广告。问题2:是的,这很危险,你必须记住同步并且无法控制谁修改了这个变量。我会完全避免使用 static 字段。

    例如EhCache 允许您分享CacheManager。这是通过net.sf.ehcache.CacheManager#singletonstatic volatile 字段实现的。现在你遇到了各种各样的问题:如果你把ehcache.jar 放在Tomcat 的/lib 中,它会按预期工作。但是,如果每个 Web 应用程序都有自己的 JAR 文件副本,则共享将不起作用,因为每个 Web 应用程序都有自己的 CacheManager 类副本。当只有一个应用程序拥有自己的ehcache.jar 时,情况会变得更糟——所有应用程序都将共享同一个CachedManager 实例,除了将ehcache.jar 打包在一起的应用程序。这样的错误很难追查...

    【讨论】:

    • 感谢您的回答!是的,每个应用服务器都应该“违反”委托算法。
    猜你喜欢
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 2020-03-08
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多