我在tomcat/webapps
文件夹下有两个应用程序.
tomcat/webapps/App1 tomcat/webapps/App2
两个应用程序共享相同的库.例如存储在哪些中tomcat/webapps/App1/WEB-INF/lib
.
两个库都在内存中加载了两次吗?
我应该把这些共享库放进去tomcat/server/lib
吗?
正如您在此处所看到的,Tomcat在您的服务器上为每个webapp创建一个类加载器.因此,如果您拥有共享同一个库的webapp1和webapp2,那么这个库确实会被加载两次.
如果由Tomcat服务器上运行的所有 Web应用程序共享,则最终可以将此库放在公共目录(tomcat-dir/common/lib)中.
我不建议将jar文件放在共享文件夹中.例如,假设您将来需要部署第三方应用程序,该应用程序在WEB-INF文件夹中具有较新版本的jar文件.对于此应用程序,jar的类将加载两次(即使它们具有相同的名称),一个来自共享文件夹,另一个来自Web应用程序文件夹.这种情况可能会导致很难找到错误.
如果jar文件位于Web应用程序文件夹中,则它们由单独的类加载器加载,并且不会相互干扰.
根据经验:这两个网络应用程序完全是相互隔离的 - 一个用户库没有在另一个用户中使用 - 因此回答你的初始问题 - 是的,它们会被加载两次.
为了回答第二个问题,你是否应该将这些库部署到Tomcat的共享目录中 - 我会说不,这就是原因:
如果将库Jar部署到共享位置(tomcat/server/lib),则该版本的库将成为在该Tomcat实例下运行的所有Web应用程序的默认值.正如您从tomcat体系结构的概述中看到的那样,类加载器在"链中"工作,单个web-app的lib文件夹是在它抛出类未找到的异常之前它将看起来的最后一个位置.在Tomcat 6和Tomcat 7中不是这样:Web应用程序lib和classes文件夹中的任何类都将在这些类之前解决,因此,这不会破坏在战争2中部署所有jar的其他应用程序.
因此,将共享库部署到该目录的问题在于它破坏了各个应用程序彼此隔离的体系结构.在您的初始示例中很好,但是如果您想部署第三方应用程序(例如,如果您正在运行使用Portlet来处理特定内容的应用程序),则会立即遇到版本依赖性问题 - 您的库的共享版本可能不正确的第三方应用程序,但因为包已经加载,你将抛出异常左右中心.
我们正在使用tomcat6并找到一个很好的方法让tomcat填充我们所有webapps需要的公共库.
在conf/catalina.properties中编辑条目common.loader.例如,在你想要分享'mylibs'的罐子附加一个额外的文件夹
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar, ${catalina.home}/lib,${catalina.home}/lib/*.jar, {catalina.home}/mylibs/*.jar
然后将所有公共库放在那里.完成.
为什么我们在所有webapps(WAR文件)中开始使用mylibs文件夹而不是WEB-INF/lib?
在WAR超过50MB线后,部署开始成为一场噩梦!
当拥有一个带有永不jar版本的webapp时,您仍然可以将其放入WEB-INF/lib中以覆盖您在mylib中的内容.