My Spring Boot application failed today:
2018-06-04 08:38:16.310 INFO 21232 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-04 08:38:16.321 ERROR 21232 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary (or give it the name 'cacheManager') or declare a specific CacheManager to use, that serves as the default one.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:777)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:139)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:30)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I kinda understand what happened, but a proper FailureAnalyzer which could tell me where those multiple CacheManagers were defined would be of great help :)
Comment From: snicoll
As this is throwing an IllegalStateException, an extension of CacheManagerValidator in the auto-configuration looks probably the best route.
Comment From: snicoll
Closing in favour of PR #13916
Comment From: mbhave
Blocked on this issue.
Comment From: snicoll
I believe that this issue can be unblocked as the referenced issue has been fixed in 6.2.0-M2. We've decided to re-throw the usual NoUniqueBeanDefinitionException with additional information. This leads a demo app to fail as follows:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.cache.CacheManager' available: no CacheResolver specified and expected a single CacheManager bean, but found 3: [firstCacheManager,secondCacheManager,thirdCacheManager] - mark one as primary or declare a specific CacheManager to use.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:279) ~[spring-context-6.2.0-SNAPSHOT.jar:6.2.0-SNAPSHOT]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1050) ~[spring-beans-6.2.0-SNAPSHOT.jar:6.2.0-SNAPSHOT]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:970) ~[spring-context-6.2.0-SNAPSHOT.jar:6.2.0-SNAPSHOT]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.2.0-SNAPSHOT.jar:6.2.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) ~[spring-boot-3.3.0-20240429.120045-407.jar:3.3.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:457) ~[spring-boot-3.3.0-20240429.120045-407.jar:3.3.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.0-20240429.120045-407.jar:3.3.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1364) ~[spring-boot-3.3.0-20240429.120045-407.jar:3.3.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1353) ~[spring-boot-3.3.0-20240429.120045-407.jar:3.3.0-SNAPSHOT]
at com.example.demo.DemoApplication.main(DemoApplication.java:15) ~[classes/:na]
Process finished with exit code 1
Looking at NoUniqueBeanDefinitionFailureAnalyzer it backs off if the description is null. It looks like that's the case here as it doesn't find a matching nested cause. In this case, the bean lookup attempt is done programmatically, so there isn't a UnsatisfiedDependencyException to provide the injection points. Perhaps this rule can be relaxed a bit to process NoUniqueBeanDefinitionException in a generic fashion?
Comment From: wilkinsona
I guess we're still blocked until we've upgraded to Framework 6.2. I'll move this into 3.x though.
Comment From: snicoll
The failure analys has been relaxed as discussed above. Strictly speaking, https://github.com/spring-projects/spring-framework/issues/33305 is required to try it against the cache manager use case and we'll update to the snapshot soon.