Skip to content

Commit f5d1a7e

Browse files
Merge pull request #3274 from chrisdennis/issue-2494-refix
Issue 2494 Refix
2 parents be0e98c + c85a888 commit f5d1a7e

File tree

3 files changed

+117
-99
lines changed

3 files changed

+117
-99
lines changed

ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java

Lines changed: 99 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@
3535
import java.io.IOException;
3636
import java.lang.management.ManagementFactory;
3737
import java.net.URI;
38-
import java.util.*;
38+
import java.util.Collections;
39+
import java.util.HashSet;
40+
import java.util.Map;
41+
import java.util.Properties;
3942
import java.util.concurrent.ConcurrentHashMap;
4043
import java.util.concurrent.ConcurrentMap;
4144

@@ -48,6 +51,8 @@
4851
import javax.management.InstanceNotFoundException;
4952
import javax.management.MBeanServer;
5053

54+
import org.ehcache.core.events.CacheManagerListener;
55+
import org.ehcache.core.spi.store.InternalCacheManager;
5156
import static org.ehcache.jsr107.CloseUtil.chain;
5257
import static org.ehcache.jsr107.CloseUtil.closeAll;
5358

@@ -61,7 +66,7 @@ class Eh107CacheManager implements CacheManager {
6166
private static final MBeanServer MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
6267

6368
private final Object cachesLock = new Object();
64-
private final ConcurrentMap<String, Eh107Cache<?, ?>> lazilyLoadedCaches = new ConcurrentHashMap<>();
69+
private final ConcurrentMap<String, Eh107Cache<?, ?>> caches = new ConcurrentHashMap<>();
6570
private final org.ehcache.CacheManager ehCacheManager;
6671
private final EhcacheCachingProvider cachingProvider;
6772
private final ClassLoader classLoader;
@@ -80,31 +85,71 @@ class Eh107CacheManager implements CacheManager {
8085
this.configurationMerger = configurationMerger;
8186
this.statisticsService = jsr107Service.getStatistics();
8287

88+
((InternalCacheManager) ehCacheManager).registerListener(new CacheManagerListener() {
89+
@Override
90+
public void cacheAdded(String alias, org.ehcache.Cache<?, ?> cache) {
91+
loadCache(alias, cache);
92+
}
93+
94+
@Override
95+
public void cacheRemoved(String alias, org.ehcache.Cache<?, ?> cache) {
96+
Eh107Cache<?, ?> jcache = caches.get(alias);
97+
if (jcache != null) {
98+
close(jcache);
99+
}
100+
}
101+
102+
@Override
103+
public void stateTransition(Status from, Status to) {
104+
}
105+
106+
});
107+
loadAllCaches();
83108
}
84109

110+
private void loadAllCaches() {
111+
for (Map.Entry<String, CacheConfiguration<?, ?>> entry : ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet()) {
112+
CacheConfiguration<?, ?> config = entry.getValue();
113+
InternalCache<?, ?> cache = (InternalCache<?, ?>) ehCacheManager.getCache(entry.getKey(), config.getKeyType(), config.getValueType());
85114

86-
private void loadCache(String cacheName) {
87-
Map<String, CacheConfiguration<?, ?>> cacheConfigurations = ehCacheManager.getRuntimeConfiguration().getCacheConfigurations();
88-
CacheConfiguration<?, ?> cacheConfiguration;
115+
loadCache(entry.getKey(), cache);
116+
}
89117

90-
if (null != (cacheConfiguration = cacheConfigurations.get(cacheName))) {
91-
Eh107Cache<?, ?> wrappedCache = wrapEhcacheCache(cacheName, cacheConfiguration);
92-
if (lazilyLoadedCaches.putIfAbsent(cacheName, wrappedCache) == null) {
93-
@SuppressWarnings("unchecked")
94-
Eh107Configuration<?, ?> configuration = wrappedCache.getConfiguration(Eh107Configuration.class);
95-
if (configuration.isManagementEnabled()) {
96-
enableManagement(wrappedCache, true);
97-
}
98-
if (configuration.isStatisticsEnabled()) {
99-
enableStatistics(wrappedCache, true);
100-
}
101-
}
118+
for (Eh107Cache<?, ?> wrappedCache : caches.values()) {
119+
wrappedCache.isClosed();
102120
}
103121
}
104122

105-
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, CacheConfiguration<K, V> ehConfig) {
106-
org.ehcache.Cache<K, V> cache = ehCacheManager.getCache(alias, ehConfig.getKeyType(), ehConfig.getValueType());
107-
return wrapEhcacheCache(alias, (InternalCache<K, V>)cache);
123+
@SuppressWarnings("unchecked")
124+
private <K, V> Cache<K, V> loadCache(String alias, org.ehcache.Cache<K, V> cache) {
125+
return (Cache<K, V>) caches.computeIfAbsent(alias, name -> {
126+
Eh107Cache<?, ?> wrappedCache = wrapEhcacheCache(name, (InternalCache<K, V>) cache);
127+
@SuppressWarnings("unchecked")
128+
Eh107Configuration<?, ?> configuration = wrappedCache.getConfiguration(Eh107Configuration.class);
129+
if (configuration.isManagementEnabled()) {
130+
enableManagement(wrappedCache, true);
131+
}
132+
if (configuration.isStatisticsEnabled()) {
133+
enableStatistics(wrappedCache, true);
134+
}
135+
return wrappedCache;
136+
});
137+
}
138+
139+
@SuppressWarnings("unchecked")
140+
private <K, V> Cache<K, V> reloadCache(String alias, Eh107Cache<K, V> jcache) {
141+
return (Cache<K, V>) caches.computeIfPresent(alias, (name, existing) -> {
142+
@SuppressWarnings("unchecked")
143+
Eh107Configuration<?, ?> oldConfiguration = existing.getConfiguration(Eh107Configuration.class);
144+
Eh107Configuration<?, ?> newConfiguration = jcache.getConfiguration(Eh107Configuration.class);
145+
if (oldConfiguration.isManagementEnabled() != newConfiguration.isManagementEnabled()) {
146+
enableManagement(jcache, newConfiguration.isManagementEnabled());
147+
}
148+
if (oldConfiguration.isStatisticsEnabled() != newConfiguration.isStatisticsEnabled()) {
149+
enableStatistics(jcache, newConfiguration.isStatisticsEnabled());
150+
}
151+
return jcache;
152+
});
108153
}
109154

110155
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, InternalCache<K, V> cache) {
@@ -167,67 +212,42 @@ public <K, V, C extends Configuration<K, V>> Cache<K, V> createCache(String cach
167212
@SuppressWarnings("unchecked")
168213
Eh107Configuration.Eh107ConfigurationWrapper<K, V> configurationWrapper = (Eh107Configuration.Eh107ConfigurationWrapper<K, V>)config;
169214
CacheConfiguration<K, V> unwrap = configurationWrapper.getCacheConfiguration();
170-
final org.ehcache.Cache<K, V> ehcache;
171215
try {
172-
ehcache = ehCacheManager.createCache(cacheName, unwrap);
216+
ehCacheManager.createCache(cacheName, unwrap);
173217
} catch (IllegalArgumentException e) {
174218
throw new CacheException("A Cache named [" + cacheName + "] already exists");
175219
}
176-
Eh107Cache<K, V> cache = wrapEhcacheCache(cacheName, (InternalCache<K, V>)ehcache);
177-
assert safeCacheRetrieval(cacheName) == null;
178-
lazilyLoadedCaches.put(cacheName, cache);
179-
180-
@SuppressWarnings("unchecked")
181-
Eh107Configuration<?, ?> configuration = cache.getConfiguration(Eh107Configuration.class);
182-
if (configuration.isManagementEnabled()) {
183-
enableManagement(cacheName, true);
184-
}
185-
186-
if (configuration.isStatisticsEnabled()) {
187-
enableStatistics(cacheName, true);
188-
}
189-
190-
return cache;
191-
}
192-
193-
ConfigurationMerger.ConfigHolder<K, V> configHolder = configurationMerger.mergeConfigurations(cacheName, config);
194-
195-
final InternalCache<K, V> ehCache;
196-
try {
197-
ehCache = (InternalCache<K, V>)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration);
198-
} catch (IllegalArgumentException e) {
199-
throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists"));
200-
} catch (Throwable t) {
201-
// something went wrong in ehcache land, make sure to clean up our stuff
202-
throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t));
203-
}
204-
205-
Eh107Cache<K, V> cache = null;
206-
CacheResources<K, V> cacheResources = configHolder.cacheResources;
207-
try {
208-
if (configHolder.useEhcacheLoaderWriter) {
209-
cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()),
210-
cacheResources.getExpiryPolicy(), cacheResources.getListenerResources());
211-
}
212-
cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache
213-
.getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this);
214-
215-
lazilyLoadedCaches.put(cacheName, cache);
216-
217-
if (configHolder.jsr107Configuration.isManagementEnabled()) {
218-
enableManagement(cacheName, true);
219-
}
220+
return safeCacheRetrieval(cacheName);
221+
} else {
222+
ConfigurationMerger.ConfigHolder<K, V> configHolder = configurationMerger.mergeConfigurations(cacheName, config);
220223

221-
if (configHolder.jsr107Configuration.isStatisticsEnabled()) {
222-
enableStatistics(cacheName, true);
224+
final InternalCache<K, V> ehCache;
225+
try {
226+
ehCache = (InternalCache<K, V>)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration);
227+
} catch (IllegalArgumentException e) {
228+
throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists"));
229+
} catch (Throwable t) {
230+
// something went wrong in ehcache land, make sure to clean up our stuff
231+
throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t));
223232
}
224233

225-
return cache;
226-
} catch (Throwable t) {
227-
if (cache != null) {
228-
throw cache.closeInternalAfter(new CacheException(t));
229-
} else {
230-
throw cacheResources.closeResourcesAfter(new CacheException(t));
234+
Eh107Cache<K, V> cache = null;
235+
CacheResources<K, V> cacheResources = configHolder.cacheResources;
236+
try {
237+
if (configHolder.useEhcacheLoaderWriter) {
238+
cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()),
239+
cacheResources.getExpiryPolicy(), cacheResources.getListenerResources());
240+
}
241+
cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache
242+
.getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this);
243+
244+
return reloadCache(cacheName, cache);
245+
} catch (Throwable t) {
246+
if (cache != null) {
247+
throw cache.closeInternalAfter(new CacheException(t));
248+
} else {
249+
throw cacheResources.closeResourcesAfter(new CacheException(t));
250+
}
231251
}
232252
}
233253
}
@@ -248,7 +268,6 @@ public String toString() {
248268
@Override
249269
public <K, V> Cache<K, V> getCache(String cacheName, Class<K> keyType, Class<V> valueType) {
250270
checkClosed();
251-
loadCache(cacheName);
252271

253272
if (cacheName == null || keyType == null || valueType == null) {
254273
throw new NullPointerException();
@@ -279,7 +298,6 @@ public <K, V> Cache<K, V> getCache(String cacheName, Class<K> keyType, Class<V>
279298
@Override
280299
public <K, V> Cache<K, V> getCache(String cacheName) {
281300
checkClosed();
282-
loadCache(cacheName);
283301

284302
if (cacheName == null) {
285303
throw new NullPointerException();
@@ -290,7 +308,7 @@ public <K, V> Cache<K, V> getCache(String cacheName) {
290308

291309
@SuppressWarnings("unchecked")
292310
private <K, V> Eh107Cache<K, V> safeCacheRetrieval(final String cacheName) {
293-
final Eh107Cache<?, ?> eh107Cache = lazilyLoadedCaches.get(cacheName);
311+
final Eh107Cache<?, ?> eh107Cache = caches.get(cacheName);
294312
if(eh107Cache != null && eh107Cache.isClosed()) {
295313
return null;
296314
}
@@ -300,7 +318,7 @@ private <K, V> Eh107Cache<K, V> safeCacheRetrieval(final String cacheName) {
300318
@Override
301319
public Iterable<String> getCacheNames() {
302320
checkClosed();
303-
return Collections.unmodifiableList(new ArrayList<>(lazilyLoadedCaches.keySet()));
321+
return Collections.unmodifiableSet(new HashSet<>(ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().keySet()));
304322
}
305323

306324
@Override
@@ -312,7 +330,7 @@ public void destroyCache(String cacheName) {
312330
synchronized (cachesLock) {
313331
checkClosed();
314332

315-
Eh107Cache<?, ?> cache = lazilyLoadedCaches.remove(cacheName);
333+
Eh107Cache<?, ?> cache = caches.remove(cacheName);
316334
if (cache == null) {
317335
// TCK expects this method to return w/o exception if named cache does
318336
// not exist
@@ -440,15 +458,15 @@ public void close() {
440458
void closeInternal() {
441459
synchronized (cachesLock) {
442460
try {
443-
closeAll(lazilyLoadedCaches.values(), (Closeable) lazilyLoadedCaches::clear, ehCacheManager);
461+
closeAll(caches.values(), (Closeable) caches::clear, ehCacheManager);
444462
} catch (IOException e) {
445463
throw new CacheException(e);
446464
}
447465
}
448466
}
449467

450468
void close(Eh107Cache<?, ?> cache) {
451-
if (lazilyLoadedCaches.remove(cache.getName(), cache)) {
469+
if (caches.remove(cache.getName(), cache)) {
452470
try {
453471
chain(
454472
() -> unregisterObject(cache.getManagementMBean()),

ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import javax.cache.spi.CachingProvider;
4949

5050
import static org.hamcrest.MatcherAssert.assertThat;
51+
import static org.hamcrest.Matchers.containsInAnyOrder;
5152
import static org.hamcrest.Matchers.empty;
5253
import static org.hamcrest.Matchers.equalTo;
5354
import static org.hamcrest.Matchers.hasItem;
@@ -69,6 +70,11 @@ public void setUp() throws Exception {
6970
.toURI(), cachingProvider.getDefaultClassLoader());
7071
}
7172

73+
@Test
74+
public void testImmediateCacheNames() {
75+
assertThat(cacheManager.getCacheNames(), containsInAnyOrder("customerCache", "productCache"));
76+
}
77+
7278
@Test
7379
public void test107CacheCanReturnCompleteConfigurationWhenNonePassedIn() {
7480
CacheManager cacheManager = cachingProvider.getCacheManager();

ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717
package org.ehcache.jsr107;
1818

19-
import org.ehcache.config.builders.CacheConfigurationBuilder;
2019
import org.ehcache.core.EhcacheManager;
2120
import org.ehcache.event.CacheEvent;
2221
import org.junit.After;
@@ -30,9 +29,13 @@
3029
import javax.cache.event.EventType;
3130
import javax.cache.spi.CachingProvider;
3231

32+
import static org.ehcache.config.builders.CacheConfigurationBuilder.newCacheConfigurationBuilder;
3333
import static org.ehcache.config.builders.ResourcePoolsBuilder.heap;
3434
import static org.hamcrest.MatcherAssert.assertThat;
35-
import static org.hamcrest.Matchers.*;
35+
import static org.hamcrest.Matchers.instanceOf;
36+
import static org.hamcrest.Matchers.is;
37+
import static org.hamcrest.Matchers.notNullValue;
38+
import static org.hamcrest.Matchers.nullValue;
3639

3740
/**
3841
* @author rism
@@ -80,28 +83,19 @@ public void testCacheEntryEventUnwrap() {
8083
}
8184

8285
@Test
83-
public void testCacheVisibilityPostUnwrap() {
86+
public void testCacheMutationViaUnwrap() {
87+
org.ehcache.CacheManager ehcacheManager = cacheManager.unwrap(org.ehcache.CacheManager.class);
88+
org.ehcache.Cache<Integer, String> cache = ehcacheManager.createCache("jcache", newCacheConfigurationBuilder(Integer.class, String.class, heap(5)));
8489

85-
CacheManager javaxCacheManager = Caching.getCachingProvider().getCacheManager();
86-
87-
org.ehcache.CacheManager cacheManager = javaxCacheManager.unwrap(org.ehcache.CacheManager.class);
88-
CacheConfigurationBuilder<Integer, String> cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, heap(5));
89-
cacheManager.createCache("jcache", cacheConfigurationBuilder);
90-
91-
Cache<Integer, String> javaxCache = javaxCacheManager.getCache("jcache", Integer.class, String.class);
90+
Cache<Integer, String> javaxCache = cacheManager.getCache("jcache", Integer.class, String.class);
9291
assertThat(javaxCache, is(notNullValue()));
9392

94-
CacheManager javaxCacheManager1 = javaxCacheManager.unwrap(javax.cache.CacheManager.class);
95-
Cache<Integer, String> javaxCache1 = javaxCacheManager1.getCache("jcache", Integer.class, String.class);
96-
assertThat(javaxCache1, is(notNullValue()));
97-
98-
org.ehcache.Cache<Integer, String> cache = cacheManager.getCache("jcache", Integer.class, String.class);
99-
assertThat(cache, is(notNullValue()));
93+
cache.put(1, "one");
10094

101-
cache.put(1,"one");
10295
assertThat(javaxCache.get(1), is("one"));
103-
assertThat(javaxCache1.get(1), is("one"));
10496

97+
ehcacheManager.removeCache("jcache");
98+
assertThat(cacheManager.getCache("jcache", Integer.class, String.class), is(nullValue()));
10599
}
106100

107101
private class EhEvent implements CacheEvent<String,String> {

0 commit comments

Comments
 (0)