From 72de4a89373b5647f3d821b8e13f5fccc04f0118 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 24 Feb 2023 16:10:49 +0000 Subject: [PATCH] Use ResourceLoader's ClassLoader to load ConfigDataLoaders Fixes gh-34372 --- .../context/config/ConfigDataEnvironment.java | 2 +- .../config/ConfigDataEnvironmentTests.java | 43 +++++++++++++++++++ .../separate-class-loader-spring.factories | 2 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/separate-class-loader-spring.factories diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java index 15c556e703..2b312d8b3c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java @@ -150,7 +150,7 @@ class ConfigDataEnvironment { this.environmentUpdateListener = (environmentUpdateListener != null) ? environmentUpdateListener : ConfigDataEnvironmentUpdateListener.NONE; this.loaders = new ConfigDataLoaders(logFactory, bootstrapContext, - SpringFactoriesLoader.forDefaultResourceLocation()); + SpringFactoriesLoader.forDefaultResourceLocation(resourceLoader.getClassLoader())); this.contributors = createContributors(binder); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java index 60e8993606..45a29ac144 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java @@ -16,8 +16,12 @@ package org.springframework.boot.context.config; +import java.io.File; +import java.io.IOException; +import java.net.URL; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -42,10 +46,12 @@ import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.mock.env.MockPropertySource; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; /** @@ -326,6 +332,33 @@ class ConfigDataEnvironmentTests { assertThat(listener.getProfiles().getActive()).containsExactly("one", "two", "three"); } + @Test + @SuppressWarnings("rawtypes") + void configDataLoadersAreLoadedUsingClassLoaderFromResourceLoader() { + ResourceLoader resourceLoader = mock(ResourceLoader.class); + ClassLoader classLoader = new ClassLoader() { + + @Override + public Enumeration getResources(String name) throws IOException { + if (SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION.equals(name)) { + return Collections.enumeration(List.of(new File( + "src/test/resources/org/springframework/boot/context/config/separate-class-loader-spring.factories") + .toURI() + .toURL())); + } + return super.getResources(name); + } + + }; + given(resourceLoader.getClassLoader()).willReturn(classLoader); + TestConfigDataEnvironment configDataEnvironment = new TestConfigDataEnvironment(this.logFactory, + this.bootstrapContext, this.environment, resourceLoader, this.additionalProfiles, null); + assertThat(configDataEnvironment).extracting("loaders.loaders") + .asList() + .extracting((item) -> (Class) item.getClass()) + .containsOnly(SeparateClassLoaderConfigDataLoader.class); + } + private String getConfigLocation(TestInfo info) { return "optional:classpath:" + info.getTestClass().get().getName().replace('.', '/') + "-" + info.getTestMethod().get().getName() + ".properties"; @@ -355,4 +388,14 @@ class ConfigDataEnvironmentTests { } + static class SeparateClassLoaderConfigDataLoader implements ConfigDataLoader { + + @Override + public ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resource) + throws IOException, ConfigDataResourceNotFoundException { + return null; + } + + } + } diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/separate-class-loader-spring.factories b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/separate-class-loader-spring.factories new file mode 100644 index 0000000000..b2d2d3181f --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/separate-class-loader-spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.context.config.ConfigDataLoader=\ +org.springframework.boot.context.config.ConfigDataEnvironmentTests.SeparateClassLoaderConfigDataLoader \ No newline at end of file