为什么log4j类由两个类加载器加载



我有一个应用程序的maven项目,我在WildFly服务器上运行它。该项目有log4j依赖项:

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>

我想获得这样的LoggerContext:

LoggerContext ctx = (LoggerContext) LogManager.getContext(false);

然而,这会导致ClassCastException:

class org.apache.logging.log4j.core.LoggerContext cannot be cast to class org.apache.logging.log4j.core.LoggerContext (org.apache.logging.log4j.core.LoggerContext is in unnamed module of loader 'deployment.WEB.war' @6e285ef6; org.apache.logging.log4j.core.LoggerContext is in unnamed module of loader 'deployment.WEB.war' @239cb91f)

经过一些调试,我发现问题是LoggerContext类是通过两个不同的类加载器加载的。这怎么可能呢?起初,我认为会有两种不同的依赖关系声明,但这可能不是问题所在。(我已将版本更改为2.17.0,并在两个LoggerContext类上调用了class.getPackage((.getSpecificationVersion((。对于这两个类,版本都已更改(。

类被加载两次的原因是什么?

由于Wildfly中存在log4j库,这些类似乎被加载了两次。

如何避免这种情况:向WEB-INF添加一个配置,以从wildfly:中排除日志库

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="logging"/>
</exclude-subsystems>
<exclusions>
<module name="org.apache.commons.logging"/>
<module name="org.apache.log4j"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.logging.jul-to-slf4j-stub"/>
<module name="org.jboss.logmanager"/>
<module name="org.jboss.logmanager.log4j"/>
<module name="org.slf4j"/>
<module name="org.slf4j.impl"/>
</exclusions>
</deployment>
</jboss-deployment-structure>

最新更新