生产环境生成Kafka事件时出现NullContextNameStrategy类找不到错误
问题描述
生产环境生成Kafka事件时,持续触发以下错误:
Caused by: o.a.k.c.c.ConfigException: Invalid value io.confluent.kafka.serializers.context.NullContextNameStrategy for configuration context.name.strategy: Class io.confluent.kafka.serializers.context.NullContextNameStrategy could not be found.
本地环境代码运行正常,Jenkins构建也全部成功。另外,运行时上下文加载器无法找到StringSerializer、KafkaJsonSchemaSerializer等Kafka类,因此在KafkaTemplate中直接实例化这些类才避免了相同的类找不到错误。另有一个服务使用完全相同的配置,但生产者可正常工作,且Jar包已包含必要依赖。
相关代码与配置
Kafka配置类
@Bean @Qualifier("json-schema") public KafkaTemplate<String, MyEvent<?>> jsonSchemaKafkaTemplate() throws ClassNotFoundException { return new KafkaTemplate<>(new DefaultKafkaProducerFactory<>(setCommonProducerProperties(), new StringSerializer(), new KafkaJsonSchemaSerializer<>())); } private Map<String, Object> setCommonProducerProperties(){ // Setting common properties Map<String, Object> configProps = setBrokerProperties(); configProps.put(ProducerConfig.RETRIES_CONFIG, KafkaPropertiesConfiguration.JsonSchemaProperties.RETRIES); configProps.put(ProducerConfig.CLIENT_ID_CONFIG, ""); // 原代码此处存在内容遗漏,保留原样 return configProps; } private Map<String, Object> setBrokerProperties() { Map<String, Object> brokerProperties = new HashMap<>(); brokerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaPropertiesConfiguration.getBroker().getBootstrapServers()); brokerProperties.put(SCHEMA_REGISTRY_URL_CONFIG, kafkaPropertiesConfiguration.getBroker().getSchemaRegistryUrl()); KafkaPropertiesConfiguration.SecurityProperties securityProperties = kafkaPropertiesConfiguration.getBroker().getSecurity(); (... Keystore and Truststore credentials) return brokerProperties; }
POM依赖配置
版本参数
<spring-kafka.version>3.1.0</spring-kafka.version> <kafka-client.version>3.6.1</kafka-client.version> <confluent.version>7.0.1</confluent.version>
具体依赖
<!-- Kafka --> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>${spring-kafka.version}</version> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka-test</artifactId> <version>${spring-kafka.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>${kafka-client.version}</version> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>${kafka-client.version}</version> <classifier>test</classifier> <scope>test</scope> </dependency> <!-- Confluent Schema Registry Client --> <dependency> <groupId>io.confluent</groupId> <artifactId>kafka-json-schema-serializer</artifactId> <version>${confluent.version}</version> </dependency> <dependency> <groupId>io.confluent</groupId> <artifactId>kafka-schema-registry-client</artifactId> <version>${confluent.version}</version> </dependency>
解决方案
1. 修复版本兼容性问题
Confluent Platform与Apache Kafka存在严格的版本对应关系,当前使用的Confluent 7.0.1仅兼容Apache Kafka 3.0.x,而项目使用了Kafka 3.6.1,版本不匹配导致类路径缺失。将Confluent版本调整为与Kafka 3.6.1匹配的7.6.1:
<confluent.version>7.6.1</confluent.version>
spring-kafka 3.1.0原生支持Kafka 3.5.x/3.6.x,无需调整;若后续仍有兼容性问题,可升级spring-kafka至3.2.0。
2. 检查依赖打包完整性
- 若为Spring Boot项目,确保
spring-boot-maven-plugin未排除Confluent相关依赖,避免打包时丢失必要类:<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 移除任何针对io.confluent包的exclude配置 --> </plugin> </plugins> </build> - 执行
mvn dependency:tree检查依赖树,确认无旧版本Confluent包冲突,若存在冲突需通过exclusions标签排除。
3. 显式配置ContextNameStrategy
在生产者配置中显式指定上下文名称策略类,确保KafkaJsonSchemaSerializer能正确加载:
private Map<String, Object> setCommonProducerProperties(){ Map<String, Object> configProps = setBrokerProperties(); // 新增配置 configProps.put(KafkaJsonSchemaSerializer.CONTEXT_NAME_STRATEGY_CONFIG, io.confluent.kafka.serializers.context.NullContextNameStrategy.class.getName()); configProps.put(ProducerConfig.RETRIES_CONFIG, KafkaPropertiesConfiguration.JsonSchemaProperties.RETRIES); configProps.put(ProducerConfig.CLIENT_ID_CONFIG, ""); return configProps; }
4. 排查类加载器问题
若部署在应用服务器(如Tomcat),确保应用类加载器优先加载自身依赖,而非服务器全局类加载器:
- 在Tomcat的
context.xml中添加配置:<Loader delegate="false"/> - 检查是否存在自定义类加载器逻辑,避免过滤Confluent相关包。
内容的提问来源于stack exchange,提问作者bilalchetaba
相关产品推荐
相关产品推荐

