Spring Boot: 2.2.7.RELEASE

Using a configuration similar to: https://springframework.guru/using-ehcache-3-in-spring-boot/

When two contexts are created that use the same cache manager and one of them is closed, it causes the cache manager to close and be invalid for further operations. Continuing tests in the unclosed context that uses the same cache manager results in cache is closed errors.

Sample repository: https://github.com/cdalexndr/spring-boot-issue-21458 Just run gradlew test, output:

Cache[testcache] is closed
java.lang.IllegalStateException: Cache[testcache] is closed
    at org.ehcache.jsr107.Eh107Cache.checkClosed(Eh107Cache.java:543)
    at org.ehcache.jsr107.Eh107Cache.get(Eh107Cache.java:88)
    at org.springframework.cache.jcache.JCacheCache.lookup(JCacheCache.java:78)
    ....

Comment From: snicoll

I don't know about TestNG and I don't have an opinion about your test setup.

JCache works with a ClassLoader cache so if you start several test contexts, you need to make sure these are properly closed. If you don't, you will end up with the problem you've described and there's nothing we can do about that.

Perhaps you should use @AutoConfigureCache to swap to an in-memory cache that doesn't have the same constraints as JCache?

Comment From: cdalexndr

@snicoll @AutoConfigureCache is a workaround but the root issue still remains.

you need to make sure these are properly closed.

I'm not manually closing the context, but using the supported annotation @DirtiesContext to trigger a context close. Spring should properly close the context when using JCache with multiple contexts.

Comment From: wilkinsona

The context is being closed in accordance with your @DirtiesContext configuration. To do anything else, the test framework would have to contain knowledge of JCache's behaviour and close the context rather than caching it. That change would have to be made in Spring Framework so, if you'd like to pursue this, please open an issue there.

Comment From: snicoll

I'm not manually closing the context, but using the supported annotation @DirtiesContext to trigger a context close.

By you, I didn't mean a manual closing of the context but a proper setup that closes the context at the right time.

Spring should properly close the context when using JCache with multiple contexts.

It does if configured correctly. You have created a link between two tests in different classes so that the second test starts before @DirtiesContext has been applied on CacheTest1. When using JCache and because it is stored in the ClassLoader you have to flag all context as dirty which is not what you're doing.

If you put @DirtiesContext on all three methods, your project builds. This aspect of JCache is annoying and the main reason I was recommending @AutoConfigureCache which, from my perspective, is not a workaround.

Comment From: cdalexndr

My issue was that while running tests, multiple contexts are created (for mocks, different props, etc) and when a @DirtiesContext test is reached the cache manager is invalidated and cannot be used by the remaining tests that run in a cached context.

So the possible workarounds are: 1. @DirtiesContext with @AutoConfigureCache so a different cache manager is destroyed with this context and other remain valid (preffered method) 2. @DirtiesContext with some functionality that will remove all cached contexts 3. Disable context cache (slow testing) 2. Disable cache for testing (ex: spring.cache.type=NONE)

Comment From: vishalzanzrukia

@cdalexndr can you help how to perform options 2 & 3 from above?

Comment From: cdalexndr

@vishalzanzrukia why not use workaround 1?

Comment From: vishalzanzrukia

@cdalexndr If I explore all the options and then only I can get which one suites best for me

Comment From: cdalexndr

@vishalzanzrukia options 2 & 3 are the hardest to implement, and requires you to inspect spring's code on how to access context cache and clear it. I haven't tested them, they are theoretical. As spring uses @DirtiesContext annotation to clear the current context from cache, you could start from there.

Comment From: vishalzanzrukia

Thank you, but DirtyContex takes more heap to create new context next time.

On Mon, Mar 8, 2021, 12:19 PM cdalexndr notifications@github.com wrote:

@vishalzanzrukia https://github.com/vishalzanzrukia options 2 & 3 are the hardest to implement, and requires you to inspect spring's code on how to access context cache and clear it. I haven't tested them, they are theoretically. As spring uses @DirtiesContext annotation to clear the current context from cache, you could start from there.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-boot/issues/21458#issuecomment-792515442, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABMJC4BYZUNHMNO2GFC66M3TCRXQFANCNFSM4NBEGGRQ .