Tomcat的common loader是不是不能引用WEB-INF/lib里面的jar?

Does common loader of Tomcat cannot refer jar inside WEB-INF/lib?

我有一个 Tomcat,其中包含 tomcat/lib 中的一些 logback*.jar jar,当我的 WEB-INF/lib 包含相同的 logback*.jar jar 时,它启动正常,但是当我去掉WEB-INF/lib的logback*.jar,然后启动会提示LoggerFactory class not found。所以我将 slf4j-api*.jar 复制到 tomcat/lib 它再次启动正常。

我很好奇普通加载器是否不能引用 WEB-INF/lib 中的 jar?

一定要把logback*.jar和依赖jar slf4j-api*.jar放在同一个地方吗?

为什么当 WEB-INF/lib 包含这些 jar 时工作正常?看起来 WEB-INF/lib 中的罐子可以替换 tomcat/lib,而反向不能。我说得对吗?

参考:https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

您有公共类加载器,它可用于服务器和所有 Web 应用程序,并且您有 Web 应用程序的类加载器,它仅可用于每个单独的 Web 应用程序。 webapp 类加载器也可以访问通用(原文如此!)类加载器,但反之则不行 - 所以你是对的。

为什么会这样?

一些资源是由服务器提供的,因此它们需要对服务器可用(而不是 只是 对 Web 应用程序可用)。想想通过 JNDI 提供的数据库驱动程序,通常由服务器启动。日志记录工具 - 特别是当它们通过服务器配置时 - 是另一个很好的候选者,就像你的情况一样。

请务必不要在类路径上复制任何 类 - 例如如果您在公共类加载器 (tomcat/lib) 中有一个 jar,请不要将它添加到 Web 应用程序的类路径中。否则,您可能会遇到看似无法解释的 ClassCastException,其中无法将对象类型转换为它自己的类型或合法的超类型(但来自不同的类加载器)

因此,如果您需要服务器类路径上的一些资源(并传递到您的 Web 应用程序),则必须将这些资源部署到公共类路径中,tomcat/lib。如果您只在 webapp 中需要它们:尽可能将它们保留在本地(这将允许同一服务器上的其他 webapps 带来他们自己的版本 - 实际上是相同的库但在不同的版本中 - 没有任何冲突)。在过去,公共类加载器被用来节省一些内存(通过不本地化每个 webapp 使用的资源),但考虑到 RAM 的价格与 jar 文件的典型大小,我不会再走那条路了。

当您 link Tomcat 8.0 文档时:确保您使用的 Tomcat 版本仍在更新。在回答这个问题时,至少 Tomcat 8.5