From 2ade122543d7cb407861efbc273da26303016c6b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 2 Jul 2018 13:55:03 +0200 Subject: [PATCH] Bypass serializable type wrapping if java.lang.Class not serializable Issue: SPR-16992 --- .../core/SerializableTypeWrapper.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java index 94fe195f23..e680ea38a4 100644 --- a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java +++ b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java @@ -56,14 +56,26 @@ import org.springframework.util.ReflectionUtils; * @author Juergen Hoeller * @since 4.0 */ -abstract class SerializableTypeWrapper { +final class SerializableTypeWrapper { private static final Class[] SUPPORTED_SERIALIZABLE_TYPES = { GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class}; + /** + * Let's test whether java.lang.Class itself is serializable... + * Otherwise we can skip our serializable type wrapping to begin with. + * This will be {@code true} on regular JVMs but {@code false} on GraalVM. + * @since 5.1 + */ + private static final boolean javaLangClassSerializable = Serializable.class.isAssignableFrom(Class.class); + static final ConcurrentReferenceHashMap cache = new ConcurrentReferenceHashMap<>(256); + private SerializableTypeWrapper() { + } + + /** * Return a {@link Serializable} variant of {@link Field#getGenericType()}. */ @@ -133,15 +145,17 @@ abstract class SerializableTypeWrapper { /** * Return a {@link Serializable} {@link Type} backed by a {@link TypeProvider} . + *

If type artifacts are generally not serializable in the current runtime + * environment, this delegate will simply return the original {@code Type} as-is. */ @Nullable static Type forTypeProvider(final TypeProvider provider) { - Assert.notNull(provider, "Provider must not be null"); + Assert.notNull(provider, "TypeProvider must not be null"); Type providedType = provider.getType(); if (providedType == null) { return null; } - if (providedType instanceof Serializable) { + if (!javaLangClassSerializable || providedType instanceof Serializable) { return providedType; } Type cached = cache.get(providedType);