java - tomcat lib文件夹中的spring jars

标签 java spring tomcat classloader

我对类加载在 tomcat 中是如何发生的完全感到困惑。如果我的问题听起来很愚蠢,请多多包涵。

我们在单个 tomcat 服务器上部署多个 spring webapps。为了减少内存占用,我们考虑在 tomcat lib 文件夹中包含 spring、hibernate 和数据库驱动程序 jar,以便所有 webapps 共享它们。

我首先将 spring 依赖项标记为 provided 并将这些 jar 复制到 tomcat lib。但是在服务器启动时,我开始收到多个 ClassNotFoundErrors,例如 commons-loggingcommons-fileuploadjackson、所以我不得不将这些 jar 也移动到 tomcat lib。

但后来这开始感觉可疑。如果将来我在我的项目中添加另一个 spring 依赖项,比如 spring-data-cassandra。我还需要移动它的依赖 jar 吗?这可能是无止境的。我也可能在运行时遇到 CNF 错误。

我尝试关注 this链接并将 spring-context 和 spring-web 带回应用程序 war 。但它不起作用,在 WebApplicationIntializer 初始化期间在某些类上得到了 ClassNotFound。我试图理解 classes getting loaded in tomcat 的顺序,但不能理解太多。

然后我找到了一个完全不同的解释 JDBC driver loading这有点与所有其他解释相矛盾,让我完全困惑。



当我阅读更多时,我认为将 spring jar 移动到 tomcat lib 不是正确的方法,但仍然没有很好的理由。那么为什么 JDBC 驱动程序有效?有人可以解释一下吗?每个 webapp 的类加载器也会创建每个类的副本吗?

编辑 1:我开始知道 spring jar 中很少有依赖项是 optional 的,如果在我的 webapp 中使用这些依赖项是必需的。所以 spring-web 依赖于 jackson 库,但对于我的应用程序是可选的。所以我需要找出我的项目需要哪些 jars 并且 spring 也需要这些 jars,这些 jars 需要移动到 tomcat lib。

最佳答案

我会尽量解释我所知道的。

当你在你的 tomcat 上部署一个 WAR 时,类加载会以这种方式发生:

  1. 在您的 WAR 类加载器中查找要加载的类
  2. 如果未找到,则移至父级(tomcat/lib 文件夹)

在你的情况下发生的事情是 spring 也有很多依赖项,如果你在你的 war 中打包它,它的依赖项也会被打包,一切都会正常工作。但是由于你将spring定义为provided,它的所有依赖也被认为是provided,当你把它放在/lib文件夹中时,spring是可以访问的,但它的依赖不是。

您需要做的是将所有spring依赖项和依赖项(等)的依赖项也放在lib文件夹中。另一种解决方案是在你的类加载层次结构中定义一个中间 WAR,它将包含你所有的公共(public)库。

关于java - tomcat lib文件夹中的spring jars,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33015844/

相关文章:

java - 绝地武士获取数据 : JedisConnectionFailureException iterating a section of code over long period of time

java - 如何为使用 WSSJInInterceptor 配置的安全性编写 WS-SecurityPolicy 条目?

java - 使用 Java Web 应用程序变得非常慢

java - xpath 查询需要 Jackrabbit sql 2 等效查询

java - 如何使用 Eclipse 插件创建搜索 View ?

java - eclipse execute jar文件在linux机器上运行

debugging - 使用本地 tomcat 服务器进行 IntelliJ 调试 gradle 构建

java - (IllegalBlockSizeException) 使用填充密码解密时,输入长度必须是 16 的倍数

java - Spring JDBC 从表中读取

tomcat - 将 war 文件从本地机器复制到 docker