Skip to content

Commit 06a3273

Browse files
committed
Fix #140: add explicit null handling for Cache deserializer
1 parent 8854403 commit 06a3273

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/cache/GuavaCacheDeserializer.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package com.fasterxml.jackson.datatype.guava.deser.cache;
22

3+
import java.io.IOException;
4+
5+
import com.google.common.cache.Cache;
6+
37
import com.fasterxml.jackson.core.JsonParser;
48
import com.fasterxml.jackson.core.JsonToken;
9+
510
import com.fasterxml.jackson.databind.*;
611
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
712
import com.fasterxml.jackson.databind.deser.NullValueProvider;
@@ -10,9 +15,7 @@
1015
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
1116
import com.fasterxml.jackson.databind.type.LogicalType;
1217
import com.fasterxml.jackson.databind.type.MapLikeType;
13-
import com.google.common.cache.Cache;
14-
15-
import java.io.IOException;
18+
import com.fasterxml.jackson.databind.util.ClassUtil;
1619

1720
public abstract class GuavaCacheDeserializer<T extends Cache<Object, Object>>
1821
extends StdDeserializer<T> implements ContextualDeserializer
@@ -146,6 +149,11 @@ private T deserializeContents(JsonParser p, DeserializationContext ctxt)
146149
} else {
147150
value = elementDeserializer.deserialize(p, ctxt);
148151
}
152+
if (value == null) {
153+
_tryToAddNull(p, ctxt, cache, key);
154+
continue;
155+
}
156+
149157
cache.put(key, value);
150158
}
151159
return cache;
@@ -157,4 +165,26 @@ private void expect(JsonParser p, JsonToken token) throws IOException {
157165
p.currentLocation());
158166
}
159167
}
168+
169+
/**
170+
* Some/many Guava containers do not allow addition of {@code null} values,
171+
* so isolate handling here.
172+
*
173+
* @since 2.17
174+
*/
175+
protected void _tryToAddNull(JsonParser p, DeserializationContext ctxt,
176+
T cache, Object key)
177+
throws IOException
178+
{
179+
// Ideally we'd have better idea of where nulls are accepted, but first
180+
// let's just produce something better than NPE:
181+
try {
182+
cache.put(key, null);
183+
} catch (NullPointerException e) {
184+
ctxt.handleUnexpectedToken(_valueType, JsonToken.VALUE_NULL, p,
185+
"Guava `Cache` of type %s does not accept `null` values",
186+
ClassUtil.classNameOf(cache));
187+
}
188+
}
189+
160190
}

guava/src/test/java/com/fasterxml/jackson/datatype/guava/CacheDeserializationTest.java

+16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.fasterxml.jackson.annotation.JsonValue;
77
import com.fasterxml.jackson.core.type.TypeReference;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
910
import com.google.common.base.Optional;
1011
import com.google.common.cache.Cache;
1112
import com.google.common.cache.CacheBuilder;
@@ -176,4 +177,19 @@ public void testWithGuavaOptional() throws Exception {
176177
// test before and after
177178
assertEquals(cache.asMap().entrySet(), deserializedCache.asMap().entrySet());
178179
}
180+
181+
// [datatypes-collections#140]: handle null values
182+
public void testCacheWithNulls() throws Exception {
183+
Cache<String, Integer> cache;
184+
try {
185+
cache = MAPPER.readValue(
186+
"{ \"key\": null }",
187+
new TypeReference<Cache<String, Integer>>() {});
188+
fail("Expected fail, deserialized as: "+cache);
189+
} catch (MismatchedInputException e) {
190+
verifyException(e, "Guava `Cache` of type");
191+
verifyException(e, "does not accept `null` values");
192+
}
193+
194+
}
179195
}

release-notes/VERSION-2.x

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Active Maintainers:
2727
(contributed by Muhammad K)
2828
#138 (guava) `GuavaCollectionDeserializer` still throws NPE in some circumstances
2929
(contributed by Arthur C)
30+
#140 (guava) `Cache` deserialization fails with NPE for `null` valued entries
3031

3132
2.16.0 (15-Nov-2023)
3233

0 commit comments

Comments
 (0)