spring testing: Another CacheManager with same name 'myCacheManager' already exists in the same VM
Asked Answered
C

5

9

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?

Candlefish answered 22/2, 2013 at 10:7 Comment(0)
R
8

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.

Rebroadcast answered 23/2, 2013 at 12:14 Comment(4)
Problem is that this happens after the test is run not before. Or said otherwise I would have to mark every single test class with this annotation to make it work. What i would need is something like @RunInOwnContext.Candlefish
Yes, it indeed means you have to annotate every test class ... unfortunately there is no other way I'm aware of.Rebroadcast
Of course you try to modify SpringJUnit4ClassRunner / TestContextManager in the way you need it ... but I don't know if that's what you really wantRebroadcast
marked as answer. There seems to be no other way than to annotate all Test classes with @DirtiesContext.Candlefish
S
7

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 :)

Stoush answered 30/11, 2015 at 12:23 Comment(1)
p:acceptExisting: should be p:acceptExisting= but Stack Overflow does not allow 1 char edits...Chirp
C
4

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.

Chrystal answered 25/6, 2014 at 6:2 Comment(2)
I have methods with @Cacheable annotation and hence a CacheManager must always be present.Candlefish
I'm running tests without a CacheManager, and the caching annotations are being ignored when running the tests. If I wanted to test the cache functionality, I would include applicationContext-cache.xml in the test setup, and also mark it with @DirtiesContext.Squireen
H
1

This happens because during testing, there are ultiple Spring application contexts existing at the same time. However, ehcache is JVM-global.

You can essentially disable Spring context caching, by creating spring.properties file on your classpath:

spring.test.context.cache.maxSize=1

Make sure that the cache manager is properly unregistered when a context is destroyed.

Havre answered 12/8, 2019 at 9:19 Comment(0)
H
0

This solved my testing issue:

spring.cache.type=none

Slightly longer version:

Julien Dubois:
I would just do spring.cache.type=none as:

  • it's much simpler
  • it would work as in the previous versions

I prefer to have the cache disabled when I do my tests - then of course there could be a very long discussion here - so that's also my favorite solution.

Detailed version (not exactly same, but similar issue):

Read this.

Handgrip answered 2/6, 2022 at 4:31 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.