如果我有两个webapps,它们的web-inf / lib目录中都有相同的第三方库jar,比如log4j .....当加载第一个webapp并创建log4j类时,这个类被加载到堆中。当加载第二个webapp并尝试加载log4j类时,它是否会在堆中找到该类并使用该类?或者它会将自己的类副本加载到堆中?
答案 0 :(得分:2)
嗯,我认为这主要是一个ClassLoader问题,它仍然依赖于你正在使用的应用服务器,但我想大多数都使用一个JVM并为每个运行的webapp保留一个ClassLoader,这样你就可以拥有不同的webapp不同版本的相同jar / clases一起运行。
例如,在tomcat中,如果需要一些共享库,可以使用/ tomcat / shared / lib文件夹放置所有webapps都可以访问的所有jar文件。
否则是的,不同的webapp不会共享同一个堆,这意味着webapp可以访问在同一个应用服务器上运行的其他webapp创建的对象
答案 1 :(得分:1)
不,它不应该。
事实类在堆上加载意味着什么都没有。因为每个类加载器都维护着自己加载的类列表。
但是,类加载器也被组织成一个树,它们应该要求它们的父类加载器首先尝试加载该类,如ClassLoader
类的javadoc中所述。
ClassLoader类使用委派模型来搜索类和资源。 ClassLoader的每个实例都有一个关联的父类加载器。当请求查找类或资源时,ClassLoader实例会在尝试查找类或资源本身之前,将对类或资源的搜索委托给其父类加载器。
但是,Web服务器通常不遵循此委派模型,以避免Web应用程序使用的Web服务器使用的库。 (此行为有时是可配置的,但它取决于您正在使用的Web服务器。)
因此在实践中,每个webapp都应该有自己独立的类空间,独立于所有其他Web应用程序,因此它们甚至可以使用同一个库的两个不同版本而没有任何问题。
另一个重要的教训是,由两个不同的类加载器加载的同一个类文件实际上是堆中的两个单独的类,而一个类中的对象将与另一个类不兼容。