Skip to content

RoutingKafkaTemplate configuration is throwing error after spring boot 3.1.2 #2921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rajadilipkolli opened this issue Dec 1, 2023 · 6 comments
Assignees
Milestone

Comments

@rajadilipkolli
Copy link
Contributor

Describe the bug

Creation of RoutingKafkaTemplate bean is failing after incrementing spring boot version to 3.1.3

To Reproduce

download/clone sample project from https://github.com/rajadilipkolli/kafka-experiments/tree/main/kafka-sample/spring-boot-multiple-producers-consumers and start it work. Configuration is present in KafkaConfig.java class

In pom.xml increment the spring boot version to 3.1.3, it starts failing.

Expected behavior

It should work in all versions as per documentation.

@artembilan
Copy link
Member

May we see some stack trace on the matter?
On the other hand, give us, please, as simple as possible project to reproduce.
Right now I see there is a Swagger which complicates things a little bit.
Also it is not clear why you show us there a consumer side if you claim that problem is with a produce one based on the RoutingKafkaTemplate.
Thanks

@rajadilipkolli
Copy link
Contributor Author

May we see some stack trace on the matter? On the other hand, give us, please, as simple as possible project to reproduce. Right now I see there is a Swagger which complicates things a little bit. Also it is not clear why you show us there a consumer side if you claim that problem is with a produce one based on the RoutingKafkaTemplate. Thanks

Below is the stack trace for the error. I will update the sample to remove swagger over the weekend

2023-12-01T21:12:04.095+05:30  INFO 31520 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
2023-12-01T21:12:04.274+05:30  WARN 31520 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
2023-12-01T21:12:04.761+05:30  INFO 31520 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-12-01T21:12:04.806+05:30  INFO 31520 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-12-01T21:12:04.851+05:30 ERROR 31520 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:764) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:241) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1193) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.context.support.DefaultLifecycleProcessor.getLifecycleBeans(DefaultLifecycleProcessor.java:395) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:243) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:201) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:965) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:619) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1342) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1331) ~[spring-boot-3.2.0.jar:3.2.0]
	at com.example.springbootkafka.multi.SpringBootKafkaMultiApplication.main(SpringBootKafkaMultiApplication.java:10) ~[classes/:na]
	at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[spring-core-6.1.1.jar:6.1.1]
	at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:49) ~[spring-core-6.1.1.jar:6.1.1]
	at org.springframework.boot.SpringApplication$Augmented.lambda$run$1(SpringApplication.java:1501) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.lambda$withHook$4(SpringApplication.java:1424) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) ~[spring-core-6.1.1.jar:6.1.1]
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) ~[spring-core-6.1.1.jar:6.1.1]
	at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1423) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication$Augmented.run(SpringApplication.java:1501) ~[spring-boot-3.2.0.jar:3.2.0]
	at com.example.springbootkafka.multi.TestSpringBootKafkaMultiApplication.main(TestSpringBootKafkaMultiApplication.java:22) ~[test-classes/:na]

Disconnected from the target VM, address: '127.0.0.1:56850', transport: 'socket'

Process finished with exit code 1

@artembilan
Copy link
Member

I think your context.registerBean(DefaultKafkaProducerFactory.class, "jsonPF", jsonPF);.
There is just no that method signature in Spring.
The closest one and which makes your code compiling is this:

public <T> void registerBean(Class<T> beanClass, Object... constructorArgs) {

But you see, one of your args is "jsonPF" string which is wrong for DefaultKafkaProducerFactory ctor.

Also look: you talked about Spring Boot 3.1.3, but your stack trace shows 3.2.0.
Therefore you made an upgrade, but didn't follow migration and deprecation.

Apparently, the method you'd like to use is this:

public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, Object... constructorArgs) {

Therefore your code has to be changed just a bit:

context.registerBean("jsonPF", DefaultKafkaProducerFactory.class, jsonPF);

I'm closing this one as Invalid since there is really no concerns from Spring for Apache Kafka perspective.

@artembilan artembilan closed this as not planned Won't fix, can't repro, duplicate, stale Dec 1, 2023
@rajadilipkolli
Copy link
Contributor Author

rajadilipkolli commented Dec 2, 2023

Hi @artembilan , I'm referring to the spring kafka documentation . Unable to figure out if it is spring issue or spring kafka issue. If it is spring kafka we need to update the documentation to reflect the same. I tried to change as per your suggestion, it is still failing.

Please find the minimal sample to reproduce issue spring-boot-multiple-producers-consumers.zip

Error Stack with spring boot 3.1.3 version. It is working for me till 3.1.2 version

2023-12-04T15:17:24.860+05:30  INFO 18680 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
2023-12-04T15:17:24.970+05:30  WARN 18680 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
2023-12-04T15:17:24.976+05:30  INFO 18680 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-12-04T15:17:24.996+05:30  INFO 18680 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-12-04T15:17:25.015+05:30 ERROR 18680 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.kafka.core.DefaultKafkaProducerFactory': Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [java.util.Map]: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:768) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1189) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.context.support.DefaultLifecycleProcessor.getLifecycleBeans(DefaultLifecycleProcessor.java:286) ~[spring-context-6.0.11.jar:6.0.11]
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:143) ~[spring-context-6.0.11.jar:6.0.11]
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:124) ~[spring-context-6.0.11.jar:6.0.11]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:958) ~[spring-context-6.0.11.jar:6.0.11]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:611) ~[spring-context-6.0.11.jar:6.0.11]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-3.1.3.jar:3.1.3]
	at com.example.springbootkafka.multi.SpringBootKafkaMultiApplication.main(SpringBootKafkaMultiApplication.java:10) ~[classes/:na]


Process finished with exit code 1

@artembilan
Copy link
Member

I don't see that you have changed guilty code:

context.registerBean(DefaultKafkaProducerFactory.class, "jsonPF", jsonPF);

it has to be:

context.registerBean("jsonPF", DefaultKafkaProducerFactory.class, () -> jsonPF);

I see that you have something in comment, but it is still wrong.
Sorry that I have confused you before.
We cannot pass an instance as a ctor arg.

Yes, that doc is wrong and I'm more than happy to fix it, but it would be great if you can confirm that it is working one as we discuss here.
Probably indeed in some previous version of Spring Framework there was any API we refer from the current doc.
I'll fix the doc shortly.

Thanks

@artembilan artembilan reopened this Dec 4, 2023
@artembilan artembilan added this to the 3.1.1 milestone Dec 4, 2023
@artembilan artembilan self-assigned this Dec 4, 2023
@rajadilipkolli
Copy link
Contributor Author

Hi @artembilan , I can confirm that it is working as expected. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants