Skip to content

Commit 06f9fb9

Browse files
committed
Refine Class serializability check for actual Graal compatibility
Issue: SPR-16992
1 parent 6bcf6ff commit 06f9fb9

File tree

1 file changed

+10
-16
lines changed

1 file changed

+10
-16
lines changed

spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.lang.reflect.WildcardType;
3232

3333
import org.springframework.lang.Nullable;
34-
import org.springframework.util.Assert;
3534
import org.springframework.util.ConcurrentReferenceHashMap;
3635
import org.springframework.util.ObjectUtils;
3736
import org.springframework.util.ReflectionUtils;
@@ -61,14 +60,6 @@ final class SerializableTypeWrapper {
6160
private static final Class<?>[] SUPPORTED_SERIALIZABLE_TYPES = {
6261
GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class};
6362

64-
/**
65-
* Let's test whether java.lang.Class itself is serializable...
66-
* Otherwise we can skip our serializable type wrapping to begin with.
67-
* This will be {@code true} on regular JVMs but {@code false} on GraalVM.
68-
* @since 5.1
69-
*/
70-
private static final boolean javaLangClassSerializable = Serializable.class.isAssignableFrom(Class.class);
71-
7263
static final ConcurrentReferenceHashMap<Type, Type> cache = new ConcurrentReferenceHashMap<>(256);
7364

7465

@@ -81,7 +72,6 @@ private SerializableTypeWrapper() {
8172
*/
8273
@Nullable
8374
public static Type forField(Field field) {
84-
Assert.notNull(field, "Field must not be null");
8575
return forTypeProvider(new FieldTypeProvider(field));
8676
}
8777

@@ -149,21 +139,25 @@ public static <T extends Type> T unwrap(T type) {
149139
* environment, this delegate will simply return the original {@code Type} as-is.
150140
*/
151141
@Nullable
152-
static Type forTypeProvider(final TypeProvider provider) {
153-
Assert.notNull(provider, "TypeProvider must not be null");
142+
static Type forTypeProvider(TypeProvider provider) {
154143
Type providedType = provider.getType();
155-
if (providedType == null) {
156-
return null;
144+
if (providedType == null || providedType instanceof Serializable) {
145+
// No serializable type wrapping necessary (e.g. for java.lang.Class)
146+
return providedType;
157147
}
158-
if (!javaLangClassSerializable || providedType instanceof Serializable) {
148+
if (!Serializable.class.isAssignableFrom(Class.class)) {
149+
// Let's skip any wrapping attempts if types are generally not serializable in
150+
// the current runtime environment (even java.lang.Class itself, e.g. on Graal)
159151
return providedType;
160152
}
153+
154+
// Obtain a serializable type proxy for the given provider...
161155
Type cached = cache.get(providedType);
162156
if (cached != null) {
163157
return cached;
164158
}
165159
for (Class<?> type : SUPPORTED_SERIALIZABLE_TYPES) {
166-
if (type.isAssignableFrom(providedType.getClass())) {
160+
if (type.isInstance(providedType)) {
167161
ClassLoader classLoader = provider.getClass().getClassLoader();
168162
Class<?>[] interfaces = new Class<?>[] {type, SerializableTypeProxy.class, Serializable.class};
169163
InvocationHandler handler = new TypeProxyInvocationHandler(provider);

0 commit comments

Comments
 (0)