Spring application fails to start because Fabric8ConfigReloadAutoConfiguration required a single bean but 2 were found

141 Views Asked by At

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:

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.

1

There are 1 best solutions below

0
On

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.