So I'm migrating a microservice from Spring Framework to Spring Boot 2.3.10.RELEASE. But when I tried to create an integration test and started it, an obscure error occurred:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.kafka.core.KafkaTemplate]: Factory method 'kafkaTemplate' threw exception; nested exception is java.lang.VerifyError: Bad return type
Exception Details:
Location:
com/fasterxml/jackson/databind/cfg/MapperBuilder.streamFactory()Lcom/fasterxml/jackson/core/TokenStreamFactory; @7: areturn
Reason:
Type 'com/fasterxml/jackson/core/JsonFactory' (current frame, stack[0]) is not assignable to 'com/fasterxml/jackson/core/TokenStreamFactory' (from method signature)
Current Frame:
bci: @7
flags: { }
locals: { 'com/fasterxml/jackson/databind/cfg/MapperBuilder' }
stack: { 'com/fasterxml/jackson/core/JsonFactory' }
Bytecode:
0x0000000: 2ab4 0002 b600 08b0
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:652)
... 333 common frames omitted
Caused by: java.lang.VerifyError: Bad return type
Exception Details:
Location:
com/fasterxml/jackson/databind/cfg/MapperBuilder.streamFactory()Lcom/fasterxml/jackson/core/TokenStreamFactory; @7: areturn
Reason:
Type 'com/fasterxml/jackson/core/JsonFactory' (current frame, stack[0]) is not assignable to 'com/fasterxml/jackson/core/TokenStreamFactory' (from method signature)
Current Frame:
bci: @7
flags: { }
locals: { 'com/fasterxml/jackson/databind/cfg/MapperBuilder' }
stack: { 'com/fasterxml/jackson/core/JsonFactory' }
Bytecode:
0x0000000: 2ab4 0002 b600 08b0
at com.fasterxml.jackson.databind.json.JsonMapper.builder(JsonMapper.java:114)
at org.springframework.kafka.support.JacksonUtils.enhancedObjectMapper(JacksonUtils.java:58)
at org.springframework.kafka.support.JacksonUtils.enhancedObjectMapper(JacksonUtils.java:47)
at org.springframework.kafka.support.DefaultKafkaHeaderMapper.<init>(DefaultKafkaHeaderMapper.java:112)
at org.springframework.kafka.support.converter.MessagingMessageConverter.<init>(MessagingMessageConverter.java:67)
at org.springframework.kafka.core.KafkaTemplate.<init>(KafkaTemplate.java:101)
at org.springframework.kafka.core.KafkaTemplate.<init>(KafkaTemplate.java:150)
at org.springframework.kafka.core.KafkaTemplate.<init>(KafkaTemplate.java:122)
at com.gdn.x.cart.v2.rest.web.config.kafka.KafkaConfig.kafkaTemplate(KafkaConfig.java:88)
at com.gdn.x.cart.v2.rest.web.config.kafka.KafkaConfig$$EnhancerBySpringCGLIB$$62380140.CGLIB$kafkaTemplate$0(<generated>)
at com.gdn.x.cart.v2.rest.web.config.kafka.KafkaConfig$$EnhancerBySpringCGLIB$$62380140$$FastClassBySpringCGLIB$$f4054673.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
at com.gdn.x.cart.v2.rest.web.config.kafka.KafkaConfig$$EnhancerBySpringCGLIB$$62380140.kafkaTemplate(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 334 common frames omitted
Here is my KafkaConfiguration:
@EnableKafka
@Configuration
public class KafkaConfig {
// Some Properties & Consumer Configurations
@Bean
public Map<String, Object> producerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBrokerList);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, KafkaProducerInterceptor.class.getName());
return props;
}
@Bean
public ProducerFactory<String, String> producerFactory() {
return new DefaultKafkaProducerFactory<>(producerConfigs());
}
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}
The service pom parent is inherited from spring-boot-starter-parent with version 2.3.10.RELEASE. The Jackson libraries versions are also inherited from that parent pom and I checked all Jackson versions are using 2.11.4, there are no conflicting dependencies. The KafkaTemplate instantiates normally when I ran the application. It only throws that error when I started the integration test. What did I miss? Is there a way to debug this?
Here's what I had tried and failed:
- Clean .m2 directory
- Declare jackson-databind version explicitly in parent POM
- Change JUnit 4 to JUnit 5
- Upgrade maven plugins to the latest
- Lower the Spring Boot version by 1