Before you mark this as duplicate please read the question first. I've read all the stuff about this exception however it does not solve the issue for me. And I do get a slightly different exception eg Another CacheManager with same name 'myCacheManager' already exists
instead of Another unnamed CacheManager already exists
.
Spring config:
<cache:annotation-driven cache-manager="cacheManager"/>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="ehcache.xml"
p:cacheManagerName="myCacheManager"
p:shared="true"/>
ehcache
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" name="myCacheManager">
</ehcache>
The Problem is that I have 1 (in the future more) test classes that test security. these classes also load a SecurityContext.xml
So most test classes have this annotations:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
However the class causing the issue:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:ApplicationContext.xml",
"classpath:SecurityContext.xml"
})
It seems since locations are different the context is loaded again but ehcacheManager is still active from previous test.
Note: this happens only when running multiple tests (eg. like clean + build). Running this test class separately works perfectly fine.
Whats the issue? How can I solve it?
Add @DirtiesContext
annotation to your test class:
@ContextConfiguration(...)
@RunWith(...)
@DirtiesContext // <== add e.g. on class level
public class MyTest {
// ...
}
This annotation indicates that the application context associated with a test is dirty and should be closed. Subsequent tests will be supplied a new context. Works on class-level and method-level.
I don't know if the question/issue are still relevent, but here's a simple/proper solution (Don't need to add @DirtiesContext in all your tests). Avoid @DirtiesContext allows you to have only one shared context for all integration tests (via run by maven for example, or run all tests in an IDE). That avoids multiple problems caused by multiple contexts started in same times.
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="ehcache.xml"
p:cacheManagerName="myCacheManager"
p:shared="${ehcacheManager.shared:true}"
p:acceptExisting:"${ehcacheManager.acceptExisting:false}"/>
In your tests (integration tests), set those properties
ehcacheManager.acceptExisting=true
ehcacheManager.shared=false
It allows Spring to create an EhcacheManager (ehcache) for each test, but if an EhcacheManager with the same name exist, Spring will just reuse it. And Spring will also not destroy/shutdown it in the context annotated with @DirtiesContext.
The idea is simple, you prevent the destroy of EhcacheManager when using @DirtiesContext.
It's applicable if you use Spring 4 and EhCache:2.5+. With Spring 3, you must an extends of EhCacheManagerFactoryBean to add these two properties.
Don't forget to clear your cache before each test :)
You can run your tests with caching disabled even if your code has methods with @Cacheable annotations.
That way you do not have to slow your test run down by marking all of your tests with @DirtiesContext.
Put the cache related Spring configurations in their own Spring config file, eg. applicationContext-cache.xml file.
Include that applicationContext-cache.xml file only when running the application live, but not in your tests.
If you specifically want to test caching, then you need the @DirtiesContext annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With