From cbc03783d051075665601c5c6d24f60e7209905e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 20 Apr 2023 14:57:37 +0100 Subject: [PATCH] Allow startup to contiune when ConnectionDetailsFactory load fails Prior to this commit, a failure to load a ConnectionDetailsFactory caused startup to fail. This causes problems when some of a factory's required classes were not available, for examle when using spring-boot-docker-compose without Actuator. Fixes gh-35100 --- .../service/connection/ConnectionDetailsFactories.java | 9 ++++++++- .../connection/ConnectionDetailsFactoriesTests.java | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) 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 80333d0f4554..2e2bc97d0049 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 @@ -24,9 +24,13 @@ import java.util.Objects; import java.util.stream.Stream; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.core.io.support.SpringFactoriesLoader.FailureHandler; import org.springframework.util.Assert; /** @@ -39,6 +43,8 @@ */ public class ConnectionDetailsFactories { + private static final Log logger = LogFactory.getLog(ConnectionDetailsFactories.class); + private List> registrations = new ArrayList<>(); public ConnectionDetailsFactories() { @@ -47,7 +53,8 @@ public ConnectionDetailsFactories() { @SuppressWarnings({ "rawtypes", "unchecked" }) ConnectionDetailsFactories(SpringFactoriesLoader loader) { - List factories = loader.load(ConnectionDetailsFactory.class); + List factories = loader.load(ConnectionDetailsFactory.class, + FailureHandler.logging(logger)); Stream> registrations = factories.stream().map(Registration::get); registrations.filter(Objects::nonNull).forEach(this.registrations::add); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoriesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoriesTests.java index 785f7707d07a..68c8bf6b0918 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoriesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoriesTests.java @@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatNoException; /** * Tests for {@link ConnectionDetailsFactories}. @@ -87,6 +88,12 @@ void getRegistrationsReturnsOrderedDelegates() { assertThat(registrations.get(2).factory()).isEqualTo(orderThree); } + @Test + void factoryLoadFailureDoesNotPreventOtherFactoriesFromLoading() { + this.loader.add(ConnectionDetailsFactory.class.getName(), "com.example.NonExistentConnectionDetailsFactory"); + assertThatNoException().isThrownBy(() -> new ConnectionDetailsFactories(this.loader)); + } + private static final class TestConnectionDetailsFactory implements ConnectionDetailsFactory, Ordered {