From c259a673d32d7891c624b56d9fcaed5fabb429a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 23 Feb 2024 09:17:01 +0100 Subject: [PATCH] Make resolution algorithm of ConnectionDetailsFactory more explicit This commit moves the resolution check for ConnectionDetailsFactory to a dedicated method to make it more clear that it is meant to verify that the implementation is resolved and can be loaded from the classpath. The previous algorithm relied on a behavior of ResolvableType that only resolves the first level generics. Further improvements in Spring Framework 6.2 make this check invalid as some implementations use a Container that can hold a nested generic. See gh-39737 --- .../ConnectionDetailsFactories.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java index d93146eb82c..441590f7dce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -122,13 +122,30 @@ public class ConnectionDetailsFactories { @SuppressWarnings("unchecked") private static Registration get(ConnectionDetailsFactory factory) { ResolvableType type = ResolvableType.forClass(ConnectionDetailsFactory.class, factory.getClass()); - if (!type.hasUnresolvableGenerics()) { - Class[] generics = type.resolveGenerics(); + Class[] generics = resolveGenerics(type); + if (generics != null) { return new Registration<>((Class) generics[0], (Class) generics[1], factory); } return null; } + /** + * Resolve the generics of the given {@link ResolvableType} or {@code null} if any + * of them cannot be resolved. + * @param type the type to inspect + * @return the resolved generics if they can be loaded from the classpath, + * {@code null} otherwise + */ + private static Class[] resolveGenerics(ResolvableType type) { + Class[] resolvedGenerics = type.resolveGenerics(); + for (Class genericRawType : resolvedGenerics) { + if (genericRawType == null) { + return null; + } + } + return resolvedGenerics; + } + } }