From f52702ea3ce77b1be00ba1aeba821198c0dde0f0 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 22 Mar 2015 10:02:36 +0100 Subject: [PATCH] Restore proper use of CacheLoader Since Guava 11, CacheLoader is only invoked with a LoadingCache but the GuavaCache wrapper is always invoking getIfPresent(), available on the main Guava Cache interface. Update GuavaCache#get to check for the presence of a LoadingCache and call the appropriate method. Issue: SPR-12842 (cherry picked from commit 9172a6d) --- .../cache/guava/GuavaCache.java | 17 +++++++++-- .../cache/guava/GuavaCacheManagerTests.java | 30 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/spring-context-support/src/main/java/org/springframework/cache/guava/GuavaCache.java b/spring-context-support/src/main/java/org/springframework/cache/guava/GuavaCache.java index 302e513fcb7..7e8b71429e8 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/guava/GuavaCache.java +++ b/spring-context-support/src/main/java/org/springframework/cache/guava/GuavaCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import java.io.Serializable; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import com.google.common.cache.LoadingCache; +import com.google.common.util.concurrent.UncheckedExecutionException; + import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; import org.springframework.util.Assert; @@ -88,8 +91,16 @@ public class GuavaCache implements Cache { @Override public ValueWrapper get(Object key) { - Object value = this.cache.getIfPresent(key); - return toWrapper(value); + if (this.cache instanceof LoadingCache) { + try { + Object value = ((LoadingCache) this.cache).get(key); + return toWrapper(value); + } + catch (ExecutionException ex) { + throw new UncheckedExecutionException(ex.getMessage(), ex); + } + } + return toWrapper(this.cache.getIfPresent(key)); } @Override diff --git a/spring-context-support/src/test/java/org/springframework/cache/guava/GuavaCacheManagerTests.java b/spring-context-support/src/test/java/org/springframework/cache/guava/GuavaCacheManagerTests.java index 1fc676ddeb9..0f7f70beaa6 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/guava/GuavaCacheManagerTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/guava/GuavaCacheManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,10 @@ package org.springframework.cache.guava; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; +import com.google.common.util.concurrent.UncheckedExecutionException; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; @@ -32,6 +35,9 @@ import static org.mockito.Mockito.*; */ public class GuavaCacheManagerTests { + @Rule + public final ExpectedException thrown = ExpectedException.none(); + @Test public void testDynamicMode() { CacheManager cm = new GuavaCacheManager(); @@ -150,6 +156,28 @@ public class GuavaCacheManagerTests { assertNotNull(cm.getCache("someCache")); } + @Test + public void cacheLoaderUseLoadingCache() { + GuavaCacheManager cm = new GuavaCacheManager("c1"); + cm.setCacheLoader(new CacheLoader() { + @Override + public Object load(Object key) throws Exception { + if ("ping".equals(key)) { + return "pong"; + } + throw new IllegalArgumentException("I only know ping"); + } + }); + Cache cache1 = cm.getCache("c1"); + Cache.ValueWrapper value = cache1.get("ping"); + assertNotNull(value); + assertEquals("pong", value.get()); + + thrown.expect(UncheckedExecutionException.class); + thrown.expectMessage("I only know ping"); + assertNull(cache1.get("foo")); + } + @SuppressWarnings("unchecked") private CacheLoader mockCacheLoader() { return mock(CacheLoader.class);