sid*_*ate 11 java spring tomcat classloader
我对tomcat中类加载的发生方式感到困惑.如果我的问题听起来很愚蠢,请耐心等待.
我们在单个tomcat服务器上部署多个spring webapps.为了减少内存占用,我们考虑在tomcat lib文件夹中安装spring,hibernate和数据库驱动程序jar,以便所有webapp共享.
我首先将spring依赖关系标记为,provided然后将这些jar复制到tomcat lib.但是,在服务器启动时,我开始越来越多ClassNotFoundErrors,像commons-logging,commons-fileupload,jackson,所以我必须将这些罐子以及到Tomcat的lib.
但后来开始感觉很可疑.如果将来我在项目中添加另一个spring依赖项,比如spring-data-cassandra.我是否还需要移动它的依赖罐子?这可能是无止境的.另外,我可能会在运行时遇到CNF错误.
我试图按照这个链接,将spring-context和spring-web带回应用程序之战.但它没有用,在WebApplicationIntializer初始化期间在某些类上得到了ClassNotFound .我试图理解在tomcat中加载的类的顺序,但是不太了解.
然后我找到了一个完全不同的JDBC驱动程序加载解释,这与所有其他解释相矛盾,让我完全糊涂了.
在我阅读更多内容时,我认为将弹簧罐移动到tomcat lib并不是一种正确的方法,但仍然没有一个好的推理.然后为什么JDBC驱动程序有效?有人可以解释一下吗?每个webapp的classloader也会创建每个类的副本吗?
编辑1:我开始知道optional春季罐子中有很少的依赖项,如果在我的webapp中使用它将是必需的.所以spring-web依赖于jackson库,但对于我的应用程序是可选的.因此,我需要找出我的项目所需的所有罐子,并且春天也需要这些罐子,这些罐子需要移动到tomcat lib.
小智 5
我将尝试解释我所知道的。
当您在 tomcat 上部署 WAR 时,类加载将以这种方式发生:
在你的情况下,spring也有很多依赖项,如果你将它打包到你的war中,它的依赖项也会被打包,一切都会正常工作。但是,由于您将 spring 定义为提供的,因此它的所有依赖项也被视为提供,并且当您将其放入 /lib 文件夹时,spring 是可访问的,但其依赖项则不可访问。
您需要做的是将所有 spring 依赖项以及依赖项的依赖项(等)也放入 lib 文件夹中。另一个解决方案是在类加载层次结构中定义一个中间 WAR,其中包含所有公共库。
| 归档时间: |
|
| 查看次数: |
3152 次 |
| 最近记录: |