0

我在 Websphere Liberty / JEE 7 中发现了一个有趣的、可能是错误的行为,我喜欢讨论这是一个错误还是一个特性。

首先,所描述的代码是我接手的一个较旧的项目,而且代码并不总是最好的或最好的方式来做某事。所以让我们进入正题:有一个实用程序jar,其中包含一个ServletContextListener。侦听器以这种方式执行 log4j 初始化,当第一次加载类时,它有一个导致 log4j 初始化的最终静态变量。

maven 构建生成两个 WAR,其中每个 WAR 包含包含 ServletContextListener 的实用程序 jar。请参阅下图以查看 EAR 的结构:

我的 EAR 结构

这意味着我有两个包含相同实用程序 jar 的 webapps,其中包含一个像这样的静态初始化程序:

private static final MyLogger LOG = Logger.getLogger("webapp-1");

这是我的观点:当我使用标准类加载器策略(parentfirst)在 Liberty 上部署它时,静态初始化只发生一次!使用 parentLast Policy 时,静态初始化会发生两次。

我和一位同事讨论过这个问题,他首先说,没关系。但越想越觉得,这种行为其实是错误的。没有办法,webapp-1 找到任何属于 webapp-2 的类,反之亦然。这就是为什么必须为每个 webapp 分别进行静态初始化(即类加载)的原因。无论哪种类加载策略,因为 Liberty 没有自己的 log4j.jar。

那么,类加载器策略与它有什么关系呢?在我看来,这应该与此无关。

你怎么看?它是 Liberty 中的一个错误,是设计/意图(请解释)还是它是什么?

请注意,我不是在寻找解决方案,有很多。我只是感兴趣,其他开发人员如何看待这个话题。

这个问题似乎只影响类的静态成员。因为 log4j 初始化是静态的,所以 log4j 是为每个 webapp 初始化还是只初始化一次(首先加载的 webapp)。

您可以通过使用来自单独 jar 的实用程序类来检查这一点,该 jar 具有静态初始化的静态成员。使用 parentFirst 策略,它只会被初始化一次。这不应该,阿飞明白。

********** 加法,灵感来自 Andy McWright ***** parentFirst: [25.07.17 15:24:39:405 MESZ] 00000063 id=40ad88b3 lassloading.internal.ContainerClassLoader$SmartClassPathImpl > getUniversalContainersForPath Entry
[user.dir].m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar [25.07.17 15:25:02:880 MESZ] 00000063 id=0f48e3d8 com.ibm.ws.classloading.internal.AppClassLoader > findOrDelegateLoadClass Entry
org.apache.log4j.Logger

parentLast: [25.07.17 15:46:38:580 MESZ] 00000064 id=1d3c9ea4 lassloading.internal.ContainerClassLoader$SmartClassPathImpl > getUniversalContainersForPath Entry
[user.dir].m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar, [25.07.17 15:46:20:471 MESZ] 00000064 id=70f6cf68 com.ibm.ws.classloading.internal.ParentLastClassLoader > loadClass Entry
org.apache.log4j.Logger [25.07.17 15:46:20:471 MESZ] 00000064 id=70f6cf68 com.ibm.ws.classloading.internal.AppClassLoader > findClass Entry
org.apache.log4j.Logger [25.07.17 15:46:20:471 MESZ] 00000064 id=70f6cf68 com.ibm.ws.classloading.internal.AppClassLoader > findClassBytes Entry
org.apache.log4j.Logger [25.07.17 15:46:20:471 MESZ] 00000064 id=70f6cf68 com.ibm.ws.classloading.internal.ContainerClassLoader > findBytes Entry
org/apache/log4j/Logger.class [25.07.17 15:46:20:471 MESZ] 00000064 id=1d3c9ea4 lassloading.internal.ContainerClassLoader$SmartClassPathImpl > getByteResourceInformation Entry
org/apache/log4j/Logger.class [25.07.17 15:46:20:471 MESZ] 00000064 id=1d3c9ea4 lassloading.internal.ContainerClassLoader$SmartClassPathImpl > getUniversalContainersForPath Entry
org/apache/log4j/Logger.class


是的,类加载是不同的。问题是,这是正确的吗?我不这么认为,我认为这是一个缺陷。

4

0 回答 0