Hi there,
I have inspected the following (somewhat related) issues, but none of them solves the problem I am experiencing: * #1393 * #1446 * #1014 * #1060 * #984
Some specs of my application: - Spring Cloud version: Greenwhich.SR3 - Spring Cloud Config Server: 2.1.4.RELEASE - Spring Boot 2.1.8
I tried several setups, which are described below. I could not get either of them working, thus leaving me stuck for now. Help or advice is greatly appreciated.
Intended Setup:
My setup is as follows:
* config server with a bootstrap.yml having spring.cloud.config.server.bootstrap: true
* a GitHub repo with configurations
* a Hashicorp vault (v.1.2.3) with secrets (referenced in GitHub configurations)
* a config-server setup with a composite environment repository setup.
The composite configuration looks as follows:
spring:
application.name: config-server
profiles:
active: composite
# Config Server Configurations
cloud:
config:
server:
# Load configurations of config-server itself from Git repository as well.
# See: https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server
bootstrap: true
composite:
# Hashicorp Vault repository for storage and reference of secrets / credentials.
- type: vault
host: localhost
port: 8200
kvVersion: 2
# GitHub repository for bootstrapping and runtime configurations
- type: git
uri: https://github.com/FWinkler79/SpringCloudPlatform-Configs.git
deleteUntrackedBranches: true
When I run config-server with this setup, I get the following error:
java.lang.IllegalStateException: No HttpServletRequest available
at org.springframework.cloud.config.server.environment.HttpRequestConfigTokenProvider.getToken(HttpRequestConfigTokenProvider.java:41) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.getToken(VaultEnvironmentRepository.java:218) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.read(VaultEnvironmentRepository.java:209) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.findOne(VaultEnvironmentRepository.java:147) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:61) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator.locate(EnvironmentRepositoryPropertySourceLocator.java:55) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:97) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:623) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:367) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
So I tried what was suggested in #1446, i.e. to add spring.cloud.config.server.vault.token
Option 1:
spring:
cloud:
config:
server:
vault:
token: root # Option 1
bootstrap: true
composite:
# Hashicorp Vault repository for storage and reference of secrets / credentials.
- type: vault
...
# GitHub repository for bootstrapping and runtime configurations
- type: git
...
As a result, I get the following error:
2019-09-30 15:35:37.714 DEBUG [config-server,,,] 69017 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : Application failed to start due to an exception
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'configTokenProvider' defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.VaultConfiguration; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]] for bean 'configTokenProvider': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:893) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:274) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:203) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:114) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:71) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:342) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:305) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
Option 2:
spring:
cloud:
config:
server:
bootstrap: true
composite:
# Hashicorp Vault repository for storage and reference of secrets / credentials.
- type: vault
token: root # Option 2
...
# GitHub repository for bootstrapping and runtime configurations
- type: git
...
As a result, I get the following error:
2019-09-30 15:40:23.455 DEBUG [config-server,,,] 69050 --- [ main] .c.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: unknown
2019-09-30 15:40:23.460 DEBUG [config-server,,,] 69050 --- [ main] o.s.boot.diagnostics.FailureAnalyzers : FailureAnalyzer org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer@7397c6 failed
java.lang.TypeNotPresentException: Type org.springframework.jdbc.CannotGetJdbcConnectionException not present
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[na:na]
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68) ~[na:na]
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138) ~[na:na]
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
at java.base/sun.reflect.generics.repository.ClassRepository.computeSuperclass(ClassRepository.java:104) ~[na:na]
at java.base/sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:86) ~[na:na]
at java.base/java.lang.Class.getGenericSuperclass(Class.java:950) ~[na:na]
at org.springframework.core.ResolvableType.getSuperType(ResolvableType.java:466) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.core.ResolvableType.as(ResolvableType.java:455) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.core.ResolvableType.forClass(ResolvableType.java:1037) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.getCauseType(AbstractFailureAnalyzer.java:56) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.analyze(AbstractFailureAnalyzer.java:33) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.diagnostics.FailureAnalyzers.analyze(FailureAnalyzers.java:110) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.diagnostics.FailureAnalyzers.reportException(FailureAnalyzers.java:103) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:813) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:798) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
at java.base/java.lang.Class.forName(Class.java:398) ~[na:na]
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[na:na]
... 21 common frames omitted
2019-09-30 15:40:23.462 ERROR [config-server,,,] 69050 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: No HttpServletRequest available
at org.springframework.cloud.config.server.environment.HttpRequestConfigTokenProvider.getToken(HttpRequestConfigTokenProvider.java:41) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.getToken(VaultEnvironmentRepository.java:218) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.read(VaultEnvironmentRepository.java:209) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.findOne(VaultEnvironmentRepository.java:147) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:61) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator.locate(EnvironmentRepositoryPropertySourceLocator.java:55) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:97) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:623) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:367) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
Alternative Setup:
I also tried without composite:
spring:
application.name: config-server
# Activate the config-server 'composite' profile
# so that it can load its own configs from Git.
profiles:
active: vault, git
# Config Server Configurations
cloud:
config:
server:
# Load configurations of config-server itself from Git repository as well.
# See: https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server
bootstrap: true
# Hashicorp Vault repository for storage and reference of secrets / credentials.
vault:
host: localhost
port: 8200
kvVersion: 2
#token: root # does neither work with nor without it.
# GitHub repository for bootstrapping and runtime configurations
git:
uri: https://github.com/FWinkler79/SpringCloudPlatform-Configs.git
deleteUntrackedBranches: true
In this setup I cannot get it to work no matter whether the spring.cloud.config.server.vault.token is set or not - getting the same kind of exceptions as above.
Sample
You can find a sample where this is shown here.
To reproduce:
* Start the Vault, executing ./scripts/startDevVault.sh
* Start config-server
Comment From: deciojr
After 4-5 days trying to implement this, I found a workaround with the following configuration
Spring cloud version: Greenwich.SR3 Spring Cloud Config Server: 2.1.4.RELEASE Spring boot: 2.1.8
bootstrap.yml
spring:
application:
name: config-server
cloud:
config:
server:
bootstrap: true
composite:
- type: vault
kv-version: 2
token: VAULT_TOKEN
vault:
token: VAULT_TOKEN
profiles:
active: composite
main:
allow-bean-definition-overriding: true
application.yml
server:
port: 8888
spring:
cloud:
config:
server:
composite:
- type: git
uri: GIT_URI
username: ${git.username}
password: ${git.password}
The only problem is that, when i query the config server at its default profile, the vault configuration gets repeated
If anyone knows how to prevent the above or the right way to do this, it would still be very much appreciated
Comment From: FWinkler79
Hi @deciojr,
great that you had a look at it, it's much appreciated. I am just not sure we should call it a "workaround", since having the vault configuration duplicated is not really clean and kind of unexpected. What do you think?
Cheers!
Comment From: deciojr
I agree. English isn't my primary language, so I couldn't think of any other word at the time.
Comment From: FWinkler79
I am wondering if this is something that the Spring team would be willing to fix.
Generally, I see a benefit in a config-server being able to bootstrap its own config from the very GitHub repo it uses to serve other services' configs from. And it's also obvious that an integration with a password Vault is a great benefit.
However, this bug makes that combination impossible to use - when I would have thought this should be the preferred setup.
How likely is it that this is getting fixed? Just asking, since otherwise we will need to go for a different, less optimal solution.
Comment From: spencergibb
There have been new options for authenticating vault. See #1475. Can this be used here?
Comment From: FWinkler79
Thanks for the hint. Unfortunately that does not help here. In the meantime I think I found the bug that causes this issue.
If evth. is configured right (i.e. as documented) I keep getting the error:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'configTokenProvider', defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
2020-01-14 18:25:27.739 DEBUG [config-server,,,] 99242 --- [ main] .c.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: unknown
2020-01-14 18:25:27.739 ERROR [config-server,,,] 99242 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'configTokenProvider' defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.VaultConfiguration; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]] for bean 'configTokenProvider': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:927) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:287) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:337) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:242) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:206) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:117) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:74) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
So I checked why this is the case, and found that there are two classes involved, one of which is not correct:
1. EnvironmentRepositoryConfiguration
1. VaultConfiguration
EnvironmentRepositoryConfiguration imports VaultConfiguration, and expects that it defines a bean named configTokenProvider. In case that bean is not defined, EnvironmentRepositoryConfiguration will declare its default fallback like this:
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(ConfigTokenProvider.class)
protected static class DefaultConfigTokenProvider {
@Bean
public ConfigTokenProvider configTokenProvider(
ObjectProvider<HttpServletRequest> httpRequest) {
return new HttpRequestConfigTokenProvider(httpRequest);
}
However, since the fallback is declared inside a static inner class, Spring evaluates that first, thus not giving VaultConfiguration a chance to provide its (proper) configTokenProvider.
This causes the error, and the default configTokenProvider simply does not work.
Note: this could even be a problem in other cases as well, as the list of imported configurations on EnvironmentRepositoryConfiguration is quite extensive.
A Possible Fix
A possible fix should be to change EnvironmentRepositoryConfiguration to not declare the fallback configTokenProvider from within an inner configuration class, but via a @Bean method like this:
// all @Imports here...
public class EnvironmentRepositoryConfiguration {
...
@Bean
@ConditionalOnMissingBean(ConfigTokenProvider.class)
public ConfigTokenProvider configTokenProvider(ObjectProvider<HttpServletRequest> httpRequest) {
return new HttpRequestConfigTokenProvider(httpRequest);
}
...
}
I was able to reproduce the erroneous behaviour in a test rig given here.
Is there a chance this can be fixed?
Comment From: spencergibb
mark yours as @Primary?
Comment From: spencergibb
PRs welcome.
Comment From: FWinkler79
Since there is no bean of mine involved, but only framework beans that I cannot mark nor re-declare, I cannot mark anything as @Primary.
I created a PR that fixes this issue, so that the intended setup will work. If the PR is merged, I will add a final description here, that shows the setup.
I tested this in my local environment, using this project setup.