2

我有一个我正在努力解决的问题。问题是我什至不知道我应该在谷歌上搜索什么,所以这就是为什么我在这里要求对 SO 做一个简短的解释。

假设我有三个项目: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 在 B 的环境中,4 在 C 的环境中)还是只有一个static int?

LE:B 和 C 都部署在同一个 Glassfish 域中。Glassfish 版本是 3.1.1。

4

2 回答 2

2

如果“A for B”和“A for C”不同,则需要为 B 和 C 创建一个部署,每个部署都包含自己的 A 副本。

最简单的方法很可能是为 B 封装 A_for_B.jar 的单独 WAR 和为 C 封装 A_for_C.jar 的单独 WAR。

于 2012-05-29T11:57:52.150 回答
2
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.

您要搜索的是“类加载器”。这种类型的对象负责加载 Java 类。JVM 加载的每个类都由其完全限定名称加载它的类加载器实例标识。这意味着在单个 JVM 中,您可以有几个完全命名为“com.example.Test”的类,每个类都由不同的类加载器加载——并且每个类都有自己的静态字段。更重要的是,这些类在运行时会被认为是不同的:将“com.example.Test”从一个类加载器转换为“com.example.Test”从某个其他类加载器会以 ClassCastException 结束。

为了避免多次加载多个公共类(如 java.util.List)的情况,类加载器通常保持在一个干净的层次结构中。每个类加载器都知道它的“父类”,即负责加载“更通用的类”的类加载器。当我们尝试加载一个类(通常是“按名称”发生)时,例如“com.example.OtherTest”,当前类加载器会尝试询问其父级是否能够加载它(然后父级依次询问其父级) , 等等)。这样,每个类都由能够加载它的最通用的类​​加载器加载(java.lang.String 将始终由标准引导类加载器加载,即使其他一些类加载器有一些不同的版本可用)。

当你部署一个战争时,glassfish 会为它创建一个单独的类加载器。类加载器知道如何从 WEB-INF/lib 和 WEB-INF/classes 加载类。它的父级是(或至少是祖父级)域类加载器,适用于所有应用程序。因此,在应用程序类加载器加载任何类之前 - 它会要求 Glassfish 执行此操作。

整个过程是相当可配置的,并且使您可以将一个通用库的副本加载到 JVM 中(例如,如果您将库放入 - AFAIR - domain1/lib/ext,它们将可供域类加载器使用,域类加载器是每个应用程序的类加载器;或者您甚至可以将它放在 JRE 的 lib/ext 文件夹中,并使其可用于主类加载器,这将为您运行的任何应用程序加载类)。在这种情况下,它们将共享静态字段。或者你可以让你的库由战争类加载器加载,并将所有静态字段“私有”给你的应用程序。

于 2012-05-29T12:35:27.183 回答