Background:
The starting point was a micro developed on top of Spring Boot 2.7.14 and Spring Cloud 2021.0.8. With K8s 1.25 the application was starting without any problem.
After the upgrade to Spring Boot 3.1.5 and Spring Cloud 2022.0.3 something got broken and I got the problem below:
{
"timestamp": "2023-12-20T10:43:37.844Z",
"severity": "error",
"message": "***************************APPLICATION FAILED TO START***************************Description:\n\nParameter 2 of method configMapPropertyChangeEventWatcher in org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8ConfigReloadAutoConfiguration required a single bean, but 2 were found:\n\t- configDataConfigMapPropertySourceLocator: a programmatically registered singleton\t- configMapPropertySourceLocator: defined by method 'configMapPropertySourceLocator' in class path resource [org/springframework/cloud/kubernetes/fabric8/config/Fabric8BootstrapConfiguration.class]\n\n\nAction:\n\nConsider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed\n ",
"service_id": "databasefe",
"metadata": {
"function": "DBFE"
},
"version": "1.2.0"}
So the thing is that:
- without changing the dependencies, except for one thing:
- remove the dependency spring-cloud-starter-bootstrap
- following the indications in section 5. Kubernetes PropertySource implementations of Spring cloud Kubernetes documentation, to adapt to the slightly modified way to read config maps.
The last bullet translates into the fact that we replaced the old bootstrap.properties
file, like so:
# Bootstrap settings for ConfigMap
spring.application.name=${SERVICE_NAME:my-app}
with a new application.properties
file:
spring.config.import=optional:kubernetes:
spring.cloud.kubernetes.config.name=${SERVICE_NAME:my-app}
Now we have Fabric8ConfigReloadAutoConfiguration
class having ambiguation problems with two beans, provided by org.springframework.cloud.kubernetes.fabric8
of type Fabric8ConfigMapPropertySourceLocator
for which I don't have any direct control, neither to mark one of them as primary, or qualify any of them.
My question is, therefore, what has changed, or what I should look at after the upgrade that is provoking this behavior that we did not have before.
This is the relevant part of the pom from which relevant dependencies are managed:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>java-dependencies-layer</artifactId>
<packaging>jar</packaging>
<name>product java dependencies layer</name>
<description>base layer for java dependencies</description>
<parent>
<groupId>com.company.product</groupId>
<artifactId>java-dependencies-aggregator</artifactId>
<version>${revision}</version>
</parent>
<properties>
<!-- Project encoding and Java version -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<revision>1.0.0-dummy</revision>
<!-- sonarqube -->
<sonar.host.url>https://sonarqube.lmera.ericsson.se</sonar.host.url>
<sonar.sources>/usr/src/app/src/main</sonar.sources>
<sonar.tests>/usr/src/app/src/test</sonar.tests>
<sonar.coverage.jacoco.xmlReportPaths>/usr/src/app/target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
</properties>
<dependencies>
<!-- 3pp dependencies start -->
<!-- Spring Framework dependencies start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-sftp</artifactId>
</dependency>
<!-- Spring Framework dependencies end -->
<!-- 3pp dependencies end -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>Application</mainClass>
<layers>
<enabled>true</enabled>
<includeLayerTools>true</includeLayerTools>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Probably related to: Spring Cloud Kubernetes app failed to start:
Any help is appreciated.
We've found the solution to this issue here: Stackoverflow: Spring Cloud Kubernetes app failed to start:. We could not remove the application.properties as we're using it to indicate the name of the configmap. Excluding spring-cloud-starter-bootstrap in the pom.xml, we solved the issue.