创建Apache Geode ClientCacheFactory时出现ClassCastException问题求助
解决Apache Geode创建ClientCacheFactory时的ClassCastException(SLF4JLogger转log4j.core.Logger失败)
问题描述
在Maven项目中使用GemFire,通过Apache Geode加载客户端缓存时,创建ClientCacheFactory对象抛出ClassCastException,异常栈如下:
java.lang.ClassCastException: org.apache.logging.slf4j.SLF4JLogger cannot be cast to org.apache.logging.log4j.core.Logger at org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider.getRootLoggerContext(Log4jLoggingProvider.java:105) ~[geode-log4j-9.10.5.jar:na] at org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider.getConfiguration(Log4jLoggingProvider.java:109) ~[geode-log4j-9.10.5.jar:na] at org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider.isUsingGemFireDefaultConfig(Log4jLoggingProvider.java:94) ~[geode-log4j-9.10.5.jar:na] at org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider.shouldUpdateLogLevels(Log4jLoggingProvider.java:143) ~[geode-log4j-9.10.5.jar:na] at org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider.configure(Log4jLoggingProvider.java:121) ~[geode-log4j-9.10.5.jar:na] at org.apache.geode.logging.internal.Configuration.configChanged(Configuration.java:143) ~[geode-core-9.10.5.jar:na] at org.apache.geode.logging.internal.Configuration.initialize(Configuration.java:132) ~[geode-core-9.10.5.jar:na] at org.apache.geode.logging.internal.LoggingSession.createSession(LoggingSession.java:69) ~[geode-core-9.10.5.jar:na] at org.apache.geode.distributed.internal.InternalDistributedSystem.initialize(InternalDistributedSystem.java:704) ~[geode-core-9.10.5.jar:na] at org.apache.geode.distributed.internal.InternalDistributedSystem.access$200(InternalDistributedSystem.java:135) ~[geode-core-9.10.5.jar:na] at org.apache.geode.distributed.internal.InternalDistributedSystemBuilder.build(InternalDistributedSystem.java:3036) ~[geode-core-9.10.5.jar:na] at org.apache.geode.distributed.internal.InternalDistributedSystem.connectInternal(InternalDistributedSystem.java:290) ~[geode-core-9.10.5.jar:na] at org.apache.geode.distributed.internal.InternalDistributedSystem.connectInternal(InternalDistributedSystem.java:216) ~[geode-core-9.10.5.jar:na] at org.apache.geode.cache.client.ClientCacheFactory.connectInternalDistributedSystem(ClientCacheFactory.java:280) ~[geode-core-9.10.5.jar:na] at org.apache.geode.cache.client.ClientCacheFactory.basicCreate(ClientCacheFactory.java:250) ~[geode-core-9.10.5.jar:na] at org.apache.geode.cache.client.ClientCacheFactory.create(ClientCacheFactory.java:216) ~[geode-core-9.10.5.jar:na]
已尝试的操作:
- 移除
log4j-over-slf4j、log4j-api和log4j-core依赖,添加slf4j-log4j12 - 排除
geode-core内部的log4j和log4j-to-slf4j依赖
当前项目依赖清单:
- log4j-slf4j-impl
- log4j-api
- log4j-core
- log4j-over-slf4j
- slf4j-api
- slf4j-log4j12
使用的Geode版本:geode-core-9.10.5,同时引入了geode-log4j和geode-logging依赖。
核心问题分析
这个异常的本质是日志桥接依赖冲突:Geode的log4j-logging-provider试图将SLF4J的Logger实例强制转为Log4j Core的Logger,说明类路径中同时存在多套日志适配桥接,导致日志上下文被SLF4J接管,而Geode期望直接使用Log4j Core。
具体解决步骤
1. 清理冲突的日志依赖,统一日志桥接方式
你的依赖中同时存在多套冲突的日志桥接组件,必须只保留一套适配逻辑:
方案A:让Geode使用SLF4J作为日志门面(推荐)
- 移除所有冲突依赖:
log4j-api、log4j-core、log4j-slf4j-impl、log4j-over-slf4j、slf4j-log4j12 - 仅保留
slf4j-api,并添加你实际使用的SLF4J绑定(比如slf4j-simple、logback-classic等) - 在Geode相关依赖中排除内置的Log4j组件:
<dependency> <groupId>org.apache.geode</groupId> <artifactId>geode-core</artifactId> <version>9.10.5</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.geode</groupId> <artifactId>geode-log4j</artifactId> <version>9.10.5</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </exclusion> </exclusions> </dependency>
方案B:强制使用Log4j 2.x作为Geode的日志实现
- 移除适配Log4j 1.x的冲突依赖:
slf4j-log4j12、log4j-over-slf4j - 保留
log4j-api、log4j-core、log4j-slf4j-impl(让SLF4J日志转发到Log4j 2) - 确保你的Log4j版本与Geode内置版本一致:执行
mvn dependency:tree查看Geode依赖的Log4j版本,保持项目依赖版本匹配,避免版本冲突
2. 验证类路径,消除重复日志类
执行mvn dependency:tree命令,检查输出中是否存在以下问题:
- 同时出现
log4j(1.x)和log4j-core(2.x) - 同时存在多个SLF4J绑定(比如
slf4j-log4j12和logback-classic) - Geode的日志依赖与项目依赖版本不一致
3. 显式指定Geode的日志提供器
在创建ClientCacheFactory之前,通过系统属性指定Geode使用的日志实现,避免自动检测时出现冲突:
// 使用Log4j 2作为日志提供器 System.setProperty("geode.logging.provider", "org.apache.geode.logging.log4j.internal.impl.Log4jLoggingProvider"); // 或者使用SLF4J作为日志提供器 // System.setProperty("geode.logging.provider", "org.apache.geode.logging.slf4j.internal.impl.Slf4jLoggingProvider");
内容的提问来源于stack exchange,提问作者ash22
相关产品推荐
相关产品推荐

