Skip to content
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

No qualifying bean of type KubernetesDiscoveryProperties when using spring-cloud-starter-bootstrap #1278

Closed
LeovR opened this issue Mar 30, 2023 · 6 comments · Fixed by #1280
Labels
Milestone

Comments

@LeovR
Copy link

LeovR commented Mar 30, 2023

Describe the bug
With the recent release of Spring Cloud 2022.0.2 our application start fails with the following exception:

  [demo] org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'servicesFunction' defined in class path resource [org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientAutoConfiguration.class]: Unsatisfied dependency expressed through method 'servicesFunction' parameter 0: No qualifying bean of type 'org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
  [demo] 	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:548) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:150) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:195) ~[spring-cloud-context-4.0.2.jar:4.0.2]
  [demo] 	at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:114) ~[spring-cloud-context-4.0.2.jar:4.0.2]
  [demo] 	at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:77) ~[spring-cloud-context-4.0.2.jar:4.0.2]
  [demo] 	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) ~[spring-context-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
  [demo] 	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:354) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:305) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[spring-boot-3.0.5.jar:3.0.5]
  [demo] 	at com.example.kubernetesdiscoveryproperties.KubernetesDiscoveryPropertiesApplication.main(KubernetesDiscoveryPropertiesApplication.java:10) ~[classes/:na]
  [demo] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
  [demo] 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1824) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1383) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ~[spring-beans-6.0.7.jar:6.0.7]
  [demo] 	... 35 common frames omitted

We are using spring-cloud-starter-kubernetes-fabric8-all with spring-cloud-starter-bootstrap and spring-cloud-starter-config with a bootstrap.yaml.

This constellation worked up to version Spring Cloud 2022.0.1.

Sample
I published a minimal reproduction project here.

@wind57
Copy link
Contributor

wind57 commented Mar 30, 2023

I'm looking at this one, will update as soon as I understand what is going on.

@wind57
Copy link
Contributor

wind57 commented Mar 30, 2023

I can reproduce this one with an integration test in our own test-suite, seems to be related to bootstrap somehow. Still have to do some digging, but the sample was very helpful...

@wind57
Copy link
Contributor

wind57 commented Mar 30, 2023

this is a bug that resulted by accident from this fix. Unfortunately, we had no integration test around it, so that it would be caught. It's also not trivial to spot just by looking at the code either, so it totally slipped under the radar for me :( .

I will fix it.

@ryanjbaxter can you add a bug label here please?

@ryanjbaxter
Copy link
Contributor

Sure.

Would the workaround for now be to create your own auto configuration for bootstrap which contains a bean for KubernetesDiscoveryProperties?

@ryanjbaxter ryanjbaxter added this to the 3.0.3 milestone Mar 30, 2023
@wind57
Copy link
Contributor

wind57 commented Mar 30, 2023

OK, so finally, after a few good hours, I am able to present my case.

In its fairness, this issue already existed event before I made my change in the fix that went into 3.0.2. I am by far not making an excuse for myself, I was just very intrigued how we did not see it happening before, once I understood the core problem.

If we modify your sample with two changes:

  • <spring-cloud.version>2022.0.1</spring-cloud.version>
  • drop the starter and replace with:
<artifactId>spring-cloud-kubernetes-fabric8-discovery</artifactId>

You are going to see that it stil fails, this time with a different dependency:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.kubernetes.commons.KubernetesClientProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

So the fact that this was not reported before is absolute luck :) I guess everyone was using the starter. I am not going to go into the details of why it does not fail with the spring-cloud-starter-kubernetes-fabric8-all unless you want me too, cause it will be pretty verbose.

The fix is trivial, and I already have a PR that fixes the issue...

@ryanjbaxter yes, your suggestion should work btw.

@LeovR
Copy link
Author

LeovR commented Mar 31, 2023

Thank you for the very quick response and PR.

@ryanjbaxter ryanjbaxter linked a pull request Mar 31, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants