-1

We are running a Spring Boot Application in Version 2.7.3 within a k8s cluster (k3s). We are using the package "spring-cloud-starter-kubernetes-client-config" to automatically retrieve the application.yaml from a config map in k8s. This is working perfectly fine.

After upgrading to spring version 3.0.4 the config map can not longer be loaded on boot. The following logs come up at startup:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.4)

2023-03-23T13:35:34.194Z  INFO 1 --- [           main] c.topsim.weasel.apigateway.Application   : Starting Application using Java 17.0.6 with PID 1 (/app/classes started by root in /)
2023-03-23T13:35:34.262Z  INFO 1 --- [           main] c.topsim.weasel.apigateway.Application   : The following 1 profile is active: "kubernetes"
2023-03-23T13:35:50.510Z  INFO 1 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=0db00e2b-900e-3a8e-ad7d-eeb09aa56d02
2023-03-23T13:35:51.311Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'io.kubernetes.client.spring.extended.manifests.config.KubernetesManifestsAutoConfiguration' of type [io.kubernetes.client.spring.extended.manifests.config.KubernetesManifestsAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.416Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration' of type [org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.453Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.457Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'loadBalancerClientsDefaultsMappingsProvider' of type [org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration$$Lambda$444/0x0000000800fd46d8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.467Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'defaultsBindHandlerAdvisor' of type [org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.549Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'kubernetes.manifests-io.kubernetes.client.spring.extended.manifests.config.KubernetesManifestsProperties' of type [io.kubernetes.client.spring.extended.manifests.config.KubernetesManifestsProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.563Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'io.kubernetes.client.spring.extended.controller.config.KubernetesInformerAutoConfiguration' of type [io.kubernetes.client.spring.extended.controller.config.KubernetesInformerAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:51.755Z  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'defaultApiClient' of type [io.kubernetes.client.openapi.ApiClient] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-03-23T13:35:55.495Z  WARN 1 --- [           main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfiguration': Unsatisfied dependency expressed through method 'setAuthenticationManager' parameter 0: Error creating bean with name 'reactiveAuthenticationManager' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Unsatisfied dependency expressed through method 'reactiveAuthenticationManager' parameter 0: Error creating bean with name 'reactiveUserDetailsService' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Failed to instantiate [org.springframework.security.core.userdetails.ReactiveUserDetailsService]: Factory method 'reactiveUserDetailsService' threw exception with message: username cannot be null
2023-03-23T13:35:55.945Z  INFO 1 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-03-23T13:35:56.145Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfiguration': Unsatisfied dependency expressed through method 'setAuthenticationManager' parameter 0: Error creating bean with name 'reactiveAuthenticationManager' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Unsatisfied dependency expressed through method 'reactiveAuthenticationManager' parameter 0: Error creating bean with name 'reactiveUserDetailsService' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Failed to instantiate [org.springframework.security.core.userdetails.ReactiveUserDetailsService]: Factory method 'reactiveUserDetailsService' threw exception with message: username cannot be null
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:817) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:769) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1408) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917) ~[spring-context-6.0.6.jar:6.0.6]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.6.jar:6.0.6]
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[spring-boot-3.0.4.jar:3.0.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-3.0.4.jar:3.0.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-3.0.4.jar:3.0.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-3.0.4.jar:3.0.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[spring-boot-3.0.4.jar:3.0.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[spring-boot-3.0.4.jar:3.0.4]
    at com.topsim.weasel.apigateway.Application.main(Application.java:10) ~[classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reactiveAuthenticationManager' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Unsatisfied dependency expressed through method 'reactiveAuthenticationManager' parameter 0: Error creating bean with name 'reactiveUserDetailsService' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Failed to instantiate [org.springframework.security.core.userdetails.ReactiveUserDetailsService]: Factory method 'reactiveUserDetailsService' threw exception with message: username cannot be null
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:548) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:809) ~[spring-beans-6.0.6.jar:6.0.6]
    ... 20 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactiveUserDetailsService' defined in class path resource [com/topsim/weasel/apigateway/security/SecurityConfiguration.class]: Failed to instantiate [org.springframework.security.core.userdetails.ReactiveUserDetailsService]: Factory method 'reactiveUserDetailsService' threw exception with message: username cannot be null
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:491) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ~[spring-beans-6.0.6.jar:6.0.6]
    ... 33 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.core.userdetails.ReactiveUserDetailsService]: Factory method 'reactiveUserDetailsService' threw exception with message: username cannot be null
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.0.6.jar:6.0.6]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-6.0.6.jar:6.0.6]
    ... 47 common frames omitted
Caused by: java.lang.IllegalArgumentException: username cannot be null
    at org.springframework.util.Assert.notNull(Assert.java:204) ~[spring-core-6.0.6.jar:6.0.6]
    at org.springframework.security.core.userdetails.User$UserBuilder.username(User.java:357) ~[spring-security-core-6.0.2.jar:6.0.2]
    at com.topsim.weasel.apigateway.security.SecurityConfiguration.reactiveUserDetailsService(SecurityConfiguration.java:67) ~[classes/:na]
    at com.topsim.weasel.apigateway.security.SecurityConfiguration$$SpringCGLIB$$0.CGLIB$reactiveUserDetailsService$1(<generated>) ~[classes/:na]
    at com.topsim.weasel.apigateway.security.SecurityConfiguration$$SpringCGLIB$$2.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.0.6.jar:6.0.6]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-6.0.6.jar:6.0.6]
    at com.topsim.weasel.apigateway.security.SecurityConfiguration$$SpringCGLIB$$0.reactiveUserDetailsService(<generated>) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.6.jar:6.0.6]
    ... 48 common frames omitted



For reference all files in the testproject are pushed to this git repo: https://github.com/topsimhick/bug-configmap-spring

  • We tried without a specific service account (not needed when still on spring version 2.7.3)
  • We added a service account, but still not working
  • We have run the application in a k3s cluster and locally in a minikube cluster (both with the same outcome)
Sascha Hick
  • 331
  • 1
  • 4
  • 9
  • please do not just post a github link, extract the relevant code so that we dont have to site and wade through your code base to try to find what the problem is. – Toerktumlare Mar 23 '23 at 21:55
  • i looked through your code, why are you are creating a `UserDetailsRepositoryReactiveAuthenticationManager` manually, and setting `setAuthenticationManager` manually? https://docs.spring.io/spring-security/reference/reactive/authorization/authorize-http-requests.html – Toerktumlare Mar 23 '23 at 22:02
  • After some trial and error we decided to switch to a simple nginx solution for a simple gateway like this. @Toerktumlare This code was written some time ago from one of our external vendors. So I cannot say why this approach was used. After a quick try by removing the manual creation, the service is not starting at all (with no logs). But for the reason stated before we probably won't go with spring for this anymore. – Sascha Hick Mar 24 '23 at 10:26

1 Answers1

0

First, to get the app running in local(not as a pod in a kubernetes cluster) connecting to my minikube namespace even with spring boot 2.7.3, I needed to add spring.main.cloud-platform and spring.cloud.kubernetes.client.namespace configs to boostrap.yml. So the bootstrap.yml ended up looking like below:

spring:
  application:
    name: api-gateway
  main:
    cloud-platform: kubernetes
  cloud:
    kubernetes:
      client:
        namespace: default

The additional change I made to get the app running with spring boot 3.0.4 was to add the spring-cloud-starter-bootstrap dependency

implementation "org.springframework.cloud:spring-cloud-starter-bootstrap"

Adding the above dependency might be the only change you need, though as per a note in the documentation, you might need to set spring.main.cloud-platform also

devatherock
  • 2,423
  • 1
  • 8
  • 23