Avoid some exception cause ClassCastException
Let's take a look at ConcurrentMapCache.java
@Override
@Nullable
public <T> T get(Object key, Callable<T> valueLoader) {
return (T) fromStoreValue(this.store.computeIfAbsent(key, k -> {
try {
return toStoreValue(valueLoader.call());
}
catch (Throwable ex) {
throw new ValueRetrievalException(key, valueLoader, ex);
}
}));
}
@Override
protected Object fromStoreValue(@Nullable Object storeValue) {
if (storeValue != null && this.serialization != null) {
try {
return super.fromStoreValue(deserializeValue(this.serialization, storeValue));
}
catch (Throwable ex) {
throw new IllegalArgumentException("Failed to deserialize cache value '" + storeValue + "'", ex);
}
}
else {
return super.fromStoreValue(storeValue);
}
}
It will throw IllegalArgumentException when there is a problem with deserialization, but not ThrowableWrapper class type, when cast to ThrowableWrapper it will cause another exception (java.lang.ClassCastException: java.lang.IllegalArgumentException cannot be cast to org.springframework.cache.interceptor.CacheOperationInvoker$ThrowableWrapper)
So we need a wrap code on this.
Comment From: pivotal-issuemaster
@WEIZIBIN Please sign the Contributor License Agreement!
Click here to manually synchronize the status of this Pull Request.
See the FAQ for frequently asked questions.
Comment From: pivotal-issuemaster
@WEIZIBIN Thank you for signing the Contributor License Agreement!
Comment From: jhoeller
While it is not typically expected for such internal deserialization to fail (since the serialized representation can only have been stored from a valid object in the same JVM run), it is a valid point that we should not attempt a hard cast of the exception there. However, the ThrowableWrapper
comment refers to what's typically propagated from the invoker; there is no need to rewrap other kinds of exceptions the same way, just to rethrow them as-is. I've repurposed the PR for that slightly different resolution. Thanks for raising this, in any case!