When a Spring Bean is named exactly like the spring boot application class a NoSuchBeanDefinitionException is thrown. The error message is quite confusing because a bean of the specific type exists on source-code level. Just because the application class is equally named it cannot be found. I think it should be possible to detect this and throw a more appropriate exception or a textual hint.

I also think that this issue is quite likely to appear in microservice-environments with a bounded context and is not just an edge-case.

Steps to reproduce: 1. Create a spring boot application

@SpringBootApplication
public class FooService {

    public static void main(String[] args) {
        SpringApplication.run(FooService.class, args);
    }
}
  1. In another package create a bean with the same name as the application class
@Service
public class FooService {
}
  1. Create a service which injects the previously created bean
@Service
public class BarService {
    private final FooService fooService;

    public BarService(FooService fooService) {
        this.fooService = fooService;
    }
}
  1. Start the application

It will produce the following output:

2022-07-23 15:49:38.770  INFO 27400 --- [           main] com.example.demo.FooService              : Starting FooService using Java 17.0.3 on DESKTOP-3FIUVON with PID 27400 (P:\tmp\spring-boot-naming-error\target\classes started by tobi in P:\tmp\spring-boot-naming-error)
2022-07-23 15:49:38.776  INFO 27400 --- [           main] com.example.demo.FooService              : No active profile set, falling back to 1 default profile: "default"
2022-07-23 15:49:39.340  WARN 27400 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'barService' defined in file [P:\tmp\spring-boot-naming-error\target\classes\com\example\demo\deeper\BarService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.deeper.FooService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2022-07-23 15:49:39.354  INFO 27400 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-07-23 15:49:39.398 ERROR 27400 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.demo.deeper.BarService required a bean of type 'com.example.demo.deeper.FooService' that could not be found.


Action:

Consider defining a bean of type 'com.example.demo.deeper.FooService' in your configuration.


Process finished with exit code 1

Comment From: snicoll

What version of Spring Boot is this? Spring Boot prevents bean overriding by default since 2.1 so I would expect a different error message.

Comment From: twobiers

I have created an example repo for this issue with Spring Boot 2.7.2: https://github.com/twobiers/spring-boot-naming-error

Personally, I had this issue with 2.6.9

Comment From: pruidong

I also reproduced this problem in Spring Boot 3.0.0-M2.

I found that the following class is not registered as a Spring Bean, so an exception is thrown when BarService is injected.

@Service
public class FooService {
}

The condition to trigger the BeanDefinitionOverrideException is that the bean is defined in two different classes:

The first class defines:

@Bean
   public BarService barService(){
     return new BarService();
   }

The second class defines:

  @Bean
   public BarService barService(){
     return new BarService();
   }

Comment From: wilkinsona

This looks like a Framework bug to me. The same underlying failure occurs with the following main class:

package com.example.demo;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class FooService {

    public static void main(String[] args) {
        try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
            ((DefaultListableBeanFactory)context.getBeanFactory()).setAllowBeanDefinitionOverriding(false);
            context.register(FooService.class);
            context.refresh();
        }
    }

}

Using this main class removes Spring Boot from the application.

com.example.demo.deeper.FooService isn't registered as, during component scanning, ClassPathBeanDefinitionScanner.isCompatible(BeanDefinition, BeanDefinition) returns true when comparing its definition with the definition for com.example.demo.FooService. In this case I don't think they should be considered to be compatible and a ConflictingBeanDefinitionException should have been thrown.

We'll transfer this to the Framework team so that they can take a look.

Comment From: stoiandelev

I have this problem in this class: package com.example.favouritePlaceInTheWorld.config;

@Configuration public class WebConfigurationInterceptor implements WebMvcConfigurer {

private final StatsInterceptor statsInterceptor;
private final IpBlackListInterceptor ipBlackListInterceptor;
private final MaintenanceInterceptor maintenanceInterceptor;

public WebConfigurationInterceptor(StatsInterceptor statsInterceptor,
                                   IpBlackListInterceptor ipBlackListInterceptor,
                                   MaintenanceInterceptor maintenanceInterceptor) {
    this.statsInterceptor = statsInterceptor;
    this.ipBlackListInterceptor = ipBlackListInterceptor;
    this.maintenanceInterceptor = maintenanceInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(statsInterceptor);
    registry.addInterceptor(ipBlackListInterceptor);
    registry.addInterceptor(maintenanceInterceptor);
}

}

When I run the app with docker I receive. NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.favouritePlaceInTheWorld.repository.IpBlockedAddressesRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} this: Any Idea?

Comment From: snicoll

@stoiandelev please ask questions on StackOverflow.

Comment From: jhoeller

Fixed as of 6.1 through #25952 already.