Tomcat的类加载器违反了委托的政策

问题描述:

  • 问题1: 我们知道,当一个类加载器将要加载一个类时,将请求委托给它的父类加载器。但是,在Tomcat中,它不会:您可以加载您的类来覆盖放在公共lib目录中的相同名称类。这意味着Tomcat WebappClassloader不遵循授权政策。这是否违反惯例?Tomcat的类加载器违反了委托的政策

  • 问题2: 我写了一个类,把它放在常用的lib目录下,显然这个类是在web应用程序之间共享的。例如,每个Web应用程序都可以读取/写入该类的静态字段。此外,JDK中的类由Bootstrap类加载器加载,然后它们的静态字段由任何Web应用程序共享,是否危险?

此行为是故意的,它允许您在每个WAR中独立重写Tomcat本身提供的库。例如,您可以为每个部署到容器的应用程序使用不同版本的Log4J,而不会引入任何问题或打破其他应用程序。从Tomcat documentation

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

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

Ad。问题2:是的,这是危险的,你必须记住关于同步并且不能控制谁修改这个变量。我会完全避免static字段。

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

+0

感谢您的回答!是的,每个应用服务器都应该“违反”授权算法。 –

+0

看到我的更新,回答你的第二个问题。 –