If I try to declare the same class twice as Spring bean and then inject it:
@Component
public class MemoryWriter {}
and
public class AppInitializer implements ApplicationContextInitializer<GenericApplicationContext>{
@Override
public void initialize(GenericApplicationContext ctx) {
ctx.registerBean(MemoryWriter.class);
}
}
then Spring Boot prints out an error and that's correct but in the second case it doesn't specify location of the class where bean is declared (just "null"):
Parameter 0 of method server in demo.AppConfig required a single bean, but 2 were found:
- demo.MemoryWriter: defined in null
- memoryWriter: defined in file [c:\demo\target\classes\demo\MemoryWriter.class]
Spring Boot: 3.0.1
Comment From: wilkinsona
The null is for the bean that was registered in the ApplicationContextInitializer. Without walking the stack, which is prohibitively slow, there's no way for the application context to know where the bean was defined. With this in mind, what would you expect the error message to say?
Comment From: sergey-morenets
Hi @wilkinsona
Well, you're Spring developer so it's up to you to make decisions on that. The message text can be "defined in unknown sources" or "defined in the application context (probably using ApplicationContextInitializer)". But I wouldn't agree about speed. This incorrect configuration would lead to application shutdown so additional milliseconds to find cause of the issue don't matter.
Comment From: philwebb
This incorrect configuration would lead to application shutdown so additional milliseconds to find cause of the issue don't matter.
I don't think we can capture the location once the application has failed, I think we'd need to capture it when the bean is defined. This would have a negative impact of successfully started apps as well.
The message text can be "defined in unknown sources"
This seems like good suggestions. We can detect null and replace it with that message.