Sometimes circular dependencies reporting functionality is not very clear and doesn't help to understand where exactly cycle happened.
Simplest example:
@Configuration
public class TestConfig {
private final MyBean1 myBean1;
public TestConfig(MyBean1 myBean1) {
this.myBean1 = myBean1;
}
@Bean
MyBean1 myBean1() {
return new MyBean1();
}
public static class MyBean1 {}
}
The report looks like this:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| testConfig defined in file [...demo-circular-report\target\classes\com\example\demo\TestConfig.class]
└─────┘
There is nothing here that indicates that it's MyBean1
that causes that circular reference.
Can the report look like this instead?
┌─────┐
| testConfig defined in file [...demo-circular-report\target\classes\com\example\demo\TestConfig.class]
| ↓
| myBean1 defined in ....
└─────┘
Or maybe myBean1
shoud be first. It's circular anyway...
This image explain more clear what's actually happened, isn't it? testConfig
bean can't be created, because myBean1
bean can't be created, because it needs testConfig
bean to be created first.
I suppose the root of the problem comes from the fact that exception also doesn't contain full graph of dependencies.
2020-08-21 19:43:31.698 WARN 10120 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testConfig' defined in file [...demo-circular-report\target\classes\com\example\demo\TestConfig.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
Names of some dependencies are just missing in this message. In this case it's myBean1
(the only reference to it is "through constructor parameter 0"). But in my real app it was even stranger. My bean1
depends on bean2
that is created in config1
but in the report it looks like my bean1
directly depends on config1
.
Maybe it's just how it works and nothing can be done here?
Comment From: snicoll
I suppose the root of the problem comes from the fact that exception also doesn't contain full graph of dependencies.
Yes. Failure Analyzer turns the exception message into something more contextualised. I've transferred this issue to the core framework as a result.
Comment From: snicoll
Unfortunately, looking at the use case, there's not much we can do about it given that the bean produced is on the same target. The current report claims a circular reference on the configuration class, which is accurate and the injection point should be looked at for more details.