Spring: another CacheManager with the same name "myCacheManager" already exists in the same virtual machine

Before you mark this as a duplicate, first read the question. I read all the materials about this exception, but this does not solve the problem for me. And I get a slightly different exception, like 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"/> 

Ehache

 <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 SecurityContext.xml

Thus, most test classes have the following annotations:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:ApplicationContext.xml") 

However, the class causes a problem:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:ApplicationContext.xml", "classpath:SecurityContext.xml" }) 

It looks like in different places the context is loading again, but ehcacheManager is still active from the previous test.

Note: this only happens when running several tests (for example, as clean + build). Running this test class separately works fine.

What is the problem? How can I solve it?

+4
source share
3 answers

Add @DirtiesContext annotation to your test class:

 @ContextConfiguration(...) @RunWith(...) @DirtiesContext // <== add eg on class level public class MyTest { // ... } 

This annotation indicates that the application context associated with the test is dirty and should be closed. Subsequent tests will be provided with a new context. It works at the class level and the method level.

+5
source

You can run tests with caching disabled , even if your code has methods with @Cacheable annotations.

That way you shouldn't slow down , your test fails, marking all your tests with @DirtiesContext.

Put the configuration associated with the Spring cache in your own Spring configuration file , for example. File applicationContext-cache.xml.

Include this applicationContext-cache.xml file only when running the live application , but not in your tests.

If you specifically want to test caching, you will need the @DirtiesContext annotation.

+2
source

I don’t know if the question / question remains relevant, but here is a simple / correct solution (no need to add @DirtiesContext to all your tests). Avoid @DirtiesContext allows you to have only one common context for all integration tests (for example, through maven or run all tests in the IDE). This avoids many problems caused by several contexts running at the same time.

 <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 these properties

 ehcacheManager.acceptExisting=true ehcacheManager.shared=false 

It allows Spring to create an EhcacheManager (ehcache) for each test, but if an EhcacheManager of the same name exists, Spring will simply reuse it. And Spring will also not destroy / turn it off in a context annotated with @DirtiesContext.

The idea is simple: you prevent EhcacheManager from being destroyed when using @DirtiesContext.

This applies if you are using Spring 4 and EhCache: 2.5+. With Spring 3, you must extend the EhCacheManagerFactoryBean to add these two properties.

Remember to clear the cache before each test :)

+1
source

All Articles