简体   繁体   English

在tomcat lib文件夹中的Spring jar

[英]Spring jars in tomcat lib folder

I am completely confused over how the class loading happens in tomcat. 我对tomcat中类加载的发生方式感到困惑。 So please bear with me if my question sounds stupid. 如果我的问题听起来很愚蠢,请耐心等待。

We deploy multiple spring webapps on single tomcat server. 我们在单个tomcat服务器上部署多个spring webapps。 To reduce the memory footprint, we thought of having spring, hibernate and database driver jars in tomcat lib folder so that those are shared by all webapps. 为了减少内存占用,我们考虑在tomcat lib文件夹中安装spring,hibernate和数据库驱动程序jar,以便所有webapp共享。

I started first by marking spring dependencies as provided and copied those jars to tomcat lib. 我首先通过标记provided spring依赖关系并将这些jar复制到tomcat lib。 But on server startup I started getting multiple ClassNotFoundErrors , like for commons-logging , commons-fileupload , jackson , so I had to move these jars as well to tomcat lib. 但是在服务器启动时,我开始获得多个ClassNotFoundErrors ,比如commons-loggingcommons-fileuploadjackson ,所以我不得不将这些jar移动到tomcat lib。

But then this started feeling fishy. 但后来开始感觉很可疑。 What if in future I add another spring dependency to my project, say spring-data-cassandra. 如果将来我在项目中添加另一个spring依赖项,比如spring-data-cassandra。 Would I need to move it's dependent jars as well? 我是否还需要移动它的依赖罐子? This might be unending. 这可能是无止境的。 Also I might get CNF errors at runtime. 我也可能在运行时遇到CNF错误。

I tried to follow this link and brought back spring-context and spring-web back to application war. 我试图按照这个链接,将spring-context和spring-web带回应用程序之战。 But it didn't work, got ClassNotFound on some class during WebApplicationIntializer initialization. 但它没有用,在WebApplicationIntializer初始化期间在某些类上获得了ClassNotFound。 I tried to understand the order of classes getting loaded in tomcat , but could not understand much. 我试图理解在tomcat中加载的顺序,但是不太了解。

Then I found a complete different explanation for JDBC driver loading which kinda contradicts to all other explanations and left me completely confused. 然后我找到了一个完全不同的JDBC驱动程序加载解释,这与所有其他解释相矛盾,让我完全糊涂了。



As I read more, I think it is not a right approach to move spring jars to tomcat lib, but still haven't got a good reasoning. 在我阅读更多内容时,我认为将弹簧罐移动到tomcat lib并不是一种正确的方法,但仍然没有一个好的推理。 And then why JDBC driver works? 然后为什么JDBC驱动程序有效? Can someone please explain? 有人可以解释一下吗? Also does classloader for each webapp creates a copy of each class? 每个webapp的classloader也会创建每个类的副本吗?

Edit 1: I came to know that few dependencies are optional in spring jars, and will be required if are in use in my webapp. 编辑1:我开始知道Spring jar中几乎没有optional依赖项,如果在我的webapp中使用它将是必需的。 So spring-web depends on jackson libraries but is optional for my app. 所以spring-web依赖于jackson库,但对我的应用程序来说是可选的。 So I need to find out which all jars are required for my project and are also required by spring, those jars need to be moved to tomcat lib. 因此,我需要找出我的项目所需的所有罐子,并且春天也需要这些罐子,这些罐子需要移动到tomcat lib。

I will try to explain what I know. 我会尝试解释我所知道的。

When you deploy a WAR on your tomcat, the class loading will happen this way : 在tomcat上部署WAR时,类加载将以这种方式进行:

  1. look for the class to load in your WAR classLoader 查找要在WAR classLoader中加载的类
  2. if not found move to parent (tomcat /lib folder) 如果没有找到移动到父(tomcat / lib文件夹)

What happen in your case is that spring also have a lot of dependencies, if you package it in your war, its dependencies would have been packaged as well and everything would have worked fine. 在你的情况下发生的事情是spring也有很多依赖关系,如果你把它打包在你的战争中,它的依赖关系也会被打包,一切都会好起来的。 But since you defined spring as provided, all its dependencies are considered provided as well, and when you put it in /lib folder, spring is accessible, but its dependencies are not. 但是由于你将spring定义为提供的,所以它的所有依赖关系都被认为是提供的,当你把它放在/ lib文件夹中时,spring是可访问的,但它的依赖关系不是。

What you need to do is put all spring dependencies and the dependencies of dependencies (etc.) in lib folder as well. 您需要做的是将所有spring依赖项和依赖项的依赖项(等)放在lib文件夹中。 Another solution is to define an intermediary WAR in your classloading hierarchy which will contains all your common libs. 另一种解决方案是在类加载层次结构中定义一个中间WAR,它将包含所有常用的库。

If you prefer to create this type of thin WAR, one solution would be to first gather all runtime/provided dependencies and then copy them explicitly under Tomcat's common (or shared) library directory: 如果您更喜欢创建这种类型的瘦WAR,一种解决方案是首先收集所有运行时/提供的依赖项,然后在Tomcat的公共(或共享)库目录下显式复制它们:

If under a Maven project, gather everything (including transitive dependencies) under target/dependency : 如果在Maven项目下,收集target/dependency下的所有内容(包括传递依赖项):

mvn dependency:copy-dependencies -DincludeScope=runtime
mvn dependency:copy-dependencies -DincludeScope=provided

Afterwards, copy to library. 然后,复制到库。 For example: 例如:

cp target/dependency/*.jar /usr/local/tomcat/lib/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM