我有一个我正在努力的问题。问题是我甚至不知道我应该在谷歌上搜索到什么,所以这就是为什么我在这里要求简短的解释。
假设我有三个项目:A,B和C.A是B和C的依赖关系.B和C是Web服务,例如可以部署在Glassfish中。在A中,有一个带有静态字段的类,比方说int
。在构建项目B时,static int
的值为3.然后,我们构建项目C,但我们将static int
的值更改为4.
问题是:当我们将B和C部署到Glassfish时,这些应用程序是在单独的“环境”中运行的,其中static int
在每个环境中具有不同的值(3个在env中,4个在env中C)或只有一个static int
?
LE:B和C都部署在同一个Glassfish域中。 Glassfish版本是3.1.1。
答案 0 :(得分:3)
如果“A for B”和“A for C”不同,则需要为B和C创建一个部署,每个部署包含其自己的A副本。
最简单的方法很可能是包含A_for_B.jar的B的单独WAR和包含A_for_C.jar的C的单独WAR。
答案 1 :(得分:3)
The problem is that I do not even know what exactly I should search for on google, so that's why I am asking for a short explanation here on SO.
您要搜索的是“Classloader”。此类对象负责加载Java类。 JVM加载的每个类都由其完全限定名称 AND 标识加载它的类加载器实例。这意味着在单个JVM中,您可以拥有几个名为“com.example.Test”的类,每个类都由不同的类加载器加载 - 并且每个类都有自己的静态字段。更重要的是,这些类在运行时会被认为是不同的:将一个类加载器中的“com.example.Test”转换为来自其他类加载器的“com.example.Test”将以ClassCastException结束。
为避免多次加载多个公共类的情况(如java.util.List),类加载器通常保持在干净的层次结构中。每个类加载器都知道它的“父”,即负责加载“更通用的类”的类加载器。当我们尝试加载一个类(通常发生在“名称”中)时,比如“com.example.OtherTest”,当前的类加载器会尝试询问它的父级是否能够加载它(并且父级依次询问它的父级, 等等)。这样每个类都由最通用的类加载器加载,该类加载器能够加载它(即使其他类加载器有一些不同的版本,java.lang.String也总是由标准的bootstrap类加载器加载)。
当你部署战争时,glassfish会为它创建一个单独的类加载器。类加载器知道如何从WEB-INF / lib和WEB-INF / classes加载类。它的父级是(或至少是祖父)域类加载器,适用于所有应用程序。因此,在应用程序类加载器加载任何类之前 - 它会要求Glassfish执行它。
整个过程是完全可配置的,使您只能将一个公共库的副本加载到JVM中(例如,如果您将库放入--AFAIR - domain1 / lib / ext,它们将可用于域类加载器,每个应用程序的类加载器的祖先;或者您甚至可以将它放在JRE的lib / ext文件夹中,并将其提供给主类加载器,它将为您运行的任何应用程序加载类。在这种情况下,他们将共享静态字段。或者您可以通过war类加载器加载库,并将所有静态字段设置为“私有”到您的应用程序。