chr*_*ney 12 java tomcat web-applications java-ee
我知道一个servlet容器,比如Apache Tomcat,在JVM的单个实例中运行,这意味着它的所有servlet都将在同一个进程中运行.
我也知道servlet容器的体系结构意味着每个Web应用程序都存在于它自己的上下文中,这表明它与其他Web应用程序是隔离的.
如下所示:
接受每个Web应用程序是孤立的,我希望您可以创建相同Web应用程序的2个副本,更改每个Web应用程序的名称和上下文路径(以及任何其他相关配置),并且并行运行它们而不会影响其他.这个问题的答案似乎支持这种观点.
然而,一位同事根据他们尝试这种做法的经验不同意.
他们拿了一个Web应用程序并尝试在同一个servlet容器中运行2个单独的实例(具有不同的名称等),并且遇到了2个实例冲突的问题(由于我没有参与该工作,我无法详细说明).
基于此,他们认为,由于Web应用程序在相同的进程空间中运行,因此它们不能被隔离,诸如类属性之类的东西最终会被无意中共享.这个答案似乎暗示了同样的事情
这两个视图似乎不兼容,所以我问你: servlet容器是否阻止部署到同一容器的Web应用程序相互冲突?
如果是的话,他们是如何做到的?
如果不是,为什么会发生干扰?
最后,在什么情况下可以分离Web应用程序冲突并导致彼此干扰?,可能涉及文件系统,本机代码或数据库连接上的资源的场景?
Ber*_*t F 16
简短的回答是servlet容器通过为每个应用程序使用单独的类加载器来隔离应用程序 - 由单独的类加载器加载的类(即使来自相同的物理类文件)彼此不同.但是,类加载器共享一个公共父类加载器,并且容器可能提供许多其他容器范围的资源,因此应用程序不会彼此完全隔离.
例如,如果两个应用程序共享一些公共代码,每个应用程序在其战争中包含相同的jar,那么每个应用程序将从jar加载它们自己的类实例,并且一个应用程序中的类的静态变量(例如,单例)将与其他应用程序中同一类的静态变量不同.
现在,举例来说,应用程序尝试使用java.util.Logger
(并且可能不会在其war文件中包含自己的Logger类实例).每个应用程序自己的类加载器都不会在war文件中找到该类,因此它们将遵循其父类加载器,这可能是共享的容器范围的类加载器.父类加载器将加载Logger类,然后两个应用程序将共享同一个Logger类.
同一容器中的Servlet将共享一些资源.我认为应该可以在同一个容器中两次部署相同的Web应用程序,前提是您为每个Web应用程序指定一个不同的名称,并且它们不会在特定资源上发生冲突.理论上这与部署两个不同的servlet相同,这些servlet碰巧具有相同的实现,我们一直在这样做.
一些共享的资源,在我的头顶(我不是专家,所以不要引用任何这个!):
毫无疑问还有更多.
如果您使用安全管理器,许多安全管理器都会对其进行保护.