Spring Kafka集成测试启动Embedded Kafka时遇ZKClientConfig缺失错误
你遇到的java.lang.NoClassDefFoundError: org/apache/zookeeper/client/ZKClientConfig确实是依赖版本不兼容导致的——虽然Spring Boot父依赖会帮我们统一大部分组件版本,但你引入的Confluent组件打破了这个兼容性,具体原因和解决方案如下:
问题根源
Spring Boot 2.3.0.RELEASE的父依赖管理的核心组件版本是:
- Spring Kafka 2.5.x
- Kafka客户端 2.5.x
- ZooKeeper 3.5.x(这个版本包含
ZKClientConfig类)
而你引入的io.confluent:kafka-avro-serializer:5.2.3属于Confluent 5.2.x版本,它依赖的是:
- Kafka 2.2.x
- ZooKeeper 3.4.x(旧版本完全没有
ZKClientConfig类)
Maven解析依赖时,Confluent带来的旧版ZooKeeper会覆盖Spring Boot管理的新版,导致Embedded Kafka启动时找不到必需的类。你之前尝试排除kafka-clients没用,因为问题根源在ZooKeeper版本,而非Kafka客户端。
解决方案
方案一:升级Confluent版本(推荐)
Confluent的版本和Kafka版本有严格的对应关系,要匹配Spring Boot 2.3.x的Kafka 2.5.x,你需要使用Confluent 5.5.x版本(比如5.5.4,稳定性较好)。修改你的kafka-avro-serializer依赖:
<dependency> <groupId>io.confluent</groupId> <artifactId>kafka-avro-serializer</artifactId> <version>5.5.4</version> </dependency>
方案二:强制统一ZooKeeper版本
如果无法升级Confluent版本,可以手动指定ZooKeeper版本为Spring Boot管理的3.5.x,覆盖Confluent带来的旧版本。在pom.xml中添加:
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.5.7</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
验证修改
修改依赖后,重新运行你的测试代码:
@ExtendWith(SpringExtension.class) @EmbeddedKafka( partitions = 1, bootstrapServersProperty = "spring.kafka.bootstrap-servers") public class KafkaTest { private static final Logger log = LoggerFactory.getLogger(KafkaTest.class); @Test public void test(EmbeddedKafkaBroker broker) { var brokerList = broker.getBrokersAsString(); log.debug("Embedded Kakfa topics {}", broker.getTopics()); } }
Embedded Kafka应该能正常启动,不会再抛出NoClassDefFoundError。
内容的提问来源于stack exchange,提问作者Nikolas

