Java Tomcat类加载器违反了委托策略
问题1: 正如我们所知,当类加载器即将加载一个类时,它将请求委托给其父类加载器。然而,在Tomcat中,情况并非如此:您可以加载类来覆盖放在公共lib目录中的同名类。这意味着TomcatJava Tomcat类加载器违反了委托策略,java,tomcat,classloader,Java,Tomcat,Classloader,问题1: 正如我们所知,当类加载器即将加载一个类时,它将请求委托给其父类加载器。然而,在Tomcat中,情况并非如此:您可以加载类来覆盖放在公共lib目录中的同名类。这意味着TomcatWebappClassloader不遵循委派策略。这是否违反了惯例 问题2: 我编写了一个类并将其放在公共lib目录中,显然该类是在web应用程序之间共享的。例如,每个web应用程序都可以读取/写入类的静态字段。此外,JDK中的类由引导类加载器加载,然后它们的静态字段由任何web应用程序共享,这有危险吗 这种行为
WebappClassloader
不遵循委派策略。这是否违反了惯例
这种行为是故意的,它允许您在每次战争中独立地重写Tomcat中提供的库。例如,对于部署到容器中的每个应用程序,您可以使用不同的版本覆盖Log4J,而不会引入任何问题或破坏其他应用程序。来自Tomcat: 与许多服务器应用程序一样,Tomcat安装了各种类加载器[…]以允许容器的不同部分,并且运行在容器上的web应用程序可以访问可用类和资源的不同存储库。此机制用于提供Servlet规范2.4版中定义的功能,特别是第9.4节和第9.6节 它确实违反了正常的委托算法,但这也是其他应用服务器的工作方式(例如JBoss) 广告问题2:是的,这很危险,你必须记住同步,不能控制谁修改这个变量。我将完全避免使用
静态
字段
例如,允许您共享。这是通过
net.sf.ehcache.CacheManager#singleton
static volatile
字段实现的。现在您遇到了各种各样的问题:如果您将ehcache.jar
放在Tomcat的/lib
中,它将按预期工作。但是,如果每个web应用程序都有自己的JAR文件副本,则共享将不起作用,因为每个web应用程序都有自己的CacheManager
类副本。当只有一个应用程序有自己的ehcache.jar
时,情况会变得更糟-除了打包在一起的ehcache.jar
之外,所有应用程序都将共享同一个CachedManager
实例。这样的错误很难找到……谢谢您的回答!是的,每个应用服务器都应该“违反”委派算法。