在Tomcat 6的lib
(${catalina.home}/lib/
)文件夹中,我有几个共享的JAR文件,例如Hibernate。
当我调试我的Web应用程序时,控制台会通过Hibernate获得大量输出,除非我将logback.xml
放在${catalina.home}/lib/
中。
以下是问题的重点:
如果我将同一个logback.xml
移到我的网络应用的/WEB-INF/lib/
文件夹,则会被忽略,就像没有文件一样 - 我得到了所有输出。
这显然与上下文有关(在我认为的Java级别上),但我无法找到有关它的信息。
请帮助我更好地理解它,基础知识。
谢谢!
答案 0 :(得分:3)
我敢打赌它与上下文无关,而是类路径层次结构。 Java基础结构提供了一种机制(ClassLoader
)来构建类路径层次结构,而Tomcat(和许多其他servlet容器/应用程序服务器一样)使用它来隔离特定应用程序中使用的不同JAR /类文件夹。
根类加载器是层次结构内可见性较低的类,嵌套类加载器可以在其作用域内查找类,或者如果找不到,则向父类加载器询问它。某些应用程序服务器允许配置类加载器以首先询问父级,然后在父级无法找到它的情况下查看自己的范围。但是,父类加载器不能永远不会从嵌套的类加载器加载类。
注意:普通文件也是如此,与logback.xml
一样。
因此,您在Tomcat的lib
文件夹中部署了一些hibernate库,该文件夹由层次结构中的根类加载器处理。当你在该文件夹中有logback.xml
文件时,它实际上与你的Hibernate JAR处于相同的类路径层次结构级别,因此Hibernate(或它使用的日志机制)可以加载文件,因为它在其范围内。 / p>
另一方面,应用程序使用的库(WEB-INF/lib
)由不同的类加载器处理,该类加载器实际上嵌套在前面提到的库中。当您将logback.xml
移动到应用程序的库文件夹时,实际上是将它移动到更宽的范围,但 因为Hibernate已被父类加载器加载,所以它无法在其中找到该文件范围 (请记住,父类加载器无法从其子代中加载类或文件,只有子代可以向父代求问)。