-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
I have just found a problem hard to diagnose that is giving challenge to IT resources.
Short summary
When running Spring Boot tests in JUnit, under certain circumstances, an infinite loop could be started that results in the following debug logs. The below logs will loop indefinitely
Spring 6.1.8
18:38:49.569 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.cache.config.internalCacheAdvisor'
18:38:49.569 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.cache.annotation.ProxyCachingConfiguration'
18:38:49.569 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Bean creation exception on singleton FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.annotation.ProxyCachingConfiguration': No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available
This causes Jenkins to hang forever (yes, pipelines should have a timeout, but for reasons beyond my control it hanged over 2 days) when the tests are run in pipeline
Anyway, fixing the problem in the code fixes the loop and tests will run
Considerations
In my project, this occurred after a misconfigured ApplicationContext failed to create a bean from an AutoConfiguration of my definition. Ultimately because of a programming error that can be fixed by carefully reading the logs.
I expected the JUnit test to fail telling me that an Autowired dependency could not be found, instead I fall into this loop.
Without enabling Spring debug log, in fact, I see the following
18:45:20.802 [main] WARN o.s.w.c.s.GenericWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountInfoHandlerDefault' defined in file [C:\...\AccountInfoHandlerDefault.class]: Unsatisfied dependency expressed through constructor parameter 1: Error creating bean with name 'accountInfoServiceBe' defined in file [C:\...\AccountInfoServiceBe.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'caeRestServiceBE': Unsatisfied dependency expressed through method 'setCaeClient' parameter 0: No qualifying bean of type 'com.acme.CaeClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
In my case, I found that the CaeClient AutoConfiguration is instantiated too early and I mispelled the @AutoConfiguration(after=xxx.class)
Minimal Reproducible Example
Unfortunately, I am not able to provide to Spring an MRE in a timely manner. The project I am working on, an actual fat monolyth that claims to be a microservice only because it is Spring Boot and runs in Openshift (with 90 seconds startup time) is composed by a huge pile of Spring Integration pipelines, 3 JPA EntityManagers with respective DataSources, 2 JMS ConnectionFactories and a pile of RestClients/WebServiceTemplates (CaeClient is based on the RestClient), for a total of 4235 beans as displayed by Ostara.
The project has weight troubles, so I don't honestly know how "minimal" an example that reproduces the problem could be, and how long it takes to create a separate project without client's code.
Some details
My test(s) are annotated with a custom meta-annotation IpeE2eTest, where they are actually end-to-ends
This and other meta-annotations define:
- Wiremock
- MockMvc
- Exclude from auto configuration tools like ActiveMq, Rabbit, Mongo, that we don't use (to save on millis)
- SqlConfig to tell that "mainTransactionManager" is the default transaction manager
- Mock stored procedures, that are not available in H2, via TestConfiguration classes
- Import some TestConfiguration beans for other purposes
- Mockito-spy some beans (this is a longer story why we put this in the meta-annotation)
So, thank you for patiently lending me your attention. I can easily reproduce the problem in the real project, but I don't know if and when I will be able to push a reproducible example. If someone is able to identify a wrong behaviour in the bean factory, welcome. I can reproduce the problem and provide any sort of additional logging, or debug Spring locally myself to find out more.
So please count on my collaboration