From 717ddac137e4a908aed0ade0935bf9dbd3535026 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Mon, 18 Aug 2025 11:44:03 +0200 Subject: [PATCH] Improve null-safety of core/spring-boot-test See gh-46926 --- .../boot/test/context/AnnotatedClassFinder.java | 6 +++--- .../boot/test/context/SpringBootContextLoader.java | 4 +++- .../runner/AbstractApplicationContextRunner.java | 4 ++-- .../boot/test/system/OutputCapture.java | 5 ++++- .../boot/test/util/TestPropertyValues.java | 10 +++++----- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/AnnotatedClassFinder.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/AnnotatedClassFinder.java index 0d129775722..aae490e2300 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/AnnotatedClassFinder.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/AnnotatedClassFinder.java @@ -40,7 +40,7 @@ import org.springframework.util.ClassUtils; */ public final class AnnotatedClassFinder { - private static final Map> cache = Collections.synchronizedMap(new Cache(40)); + private static final Map> cache = Collections.synchronizedMap(new Cache(40)); private final Class annotationType; @@ -110,7 +110,7 @@ public final class AnnotatedClassFinder { /** * Cache implementation based on {@link LinkedHashMap}. */ - private static class Cache extends LinkedHashMap> { + private static class Cache extends LinkedHashMap> { private final int maxSize; @@ -120,7 +120,7 @@ public final class AnnotatedClassFinder { } @Override - protected boolean removeEldestEntry(Map.Entry> eldest) { + protected boolean removeEldestEntry(Map.Entry> eldest) { return size() > this.maxSize; } diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 65fb88a6f91..fb23c4cf6ae 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -553,7 +553,9 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao @Override public void failed(@Nullable ConfigurableApplicationContext context, Throwable exception) { - ContextLoaderHook.this.failedContexts.add(context); + if (context != null) { + ContextLoaderHook.this.failedContexts.add(context); + } } }; diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java index 407cc064d4f..7afc3a65ece 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java @@ -432,7 +432,7 @@ public abstract class AbstractApplicationContextRunner registration.apply(context)); this.runnerConfiguration.initializers.forEach((initializer) -> initializer.initialize(context)); if (!CollectionUtils.isEmpty(this.runnerConfiguration.configurations)) { - BiConsumer, String> registrar = getRegistrar(context); + BiConsumer, @Nullable String> registrar = getRegistrar(context); for (Configurations configurations : Configurations.collate(this.runnerConfiguration.configurations)) { for (Class beanClass : Configurations.getClasses(configurations)) { String beanName = configurations.getBeanName(beanClass); @@ -445,7 +445,7 @@ public abstract class AbstractApplicationContextRunner, String> getRegistrar(C context) { + private BiConsumer, @Nullable String> getRegistrar(C context) { if (context instanceof BeanDefinitionRegistry registry) { return new AnnotatedBeanDefinitionReader(registry, context.getEnvironment())::registerBean; } diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/system/OutputCapture.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/system/OutputCapture.java index 0cb3b97c6c5..a856c280161 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/system/OutputCapture.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/system/OutputCapture.java @@ -139,7 +139,10 @@ class OutputCapture implements CapturedOutput { */ void reset() { clearExisting(); - this.systemCaptures.peek().reset(); + SystemCapture peeked = this.systemCaptures.peek(); + if (peeked != null) { + peeked.reset(); + } } void clearExisting() { diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/util/TestPropertyValues.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/util/TestPropertyValues.java index d2ff23717d3..3c435bc411d 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/util/TestPropertyValues.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/util/TestPropertyValues.java @@ -56,9 +56,9 @@ public final class TestPropertyValues { private static final TestPropertyValues EMPTY = new TestPropertyValues(Collections.emptyMap()); - private final Map properties; + private final Map properties; - private TestPropertyValues(Map properties) { + private TestPropertyValues(Map properties) { this.properties = Collections.unmodifiableMap(properties); } @@ -117,7 +117,7 @@ public final class TestPropertyValues { if (stream == null) { return this; } - Map properties = new LinkedHashMap<>(this.properties); + Map properties = new LinkedHashMap<>(this.properties); stream.map(mapper).filter(Objects::nonNull).forEach((pair) -> pair.addTo(properties)); return new TestPropertyValues(properties); } @@ -175,7 +175,7 @@ public final class TestPropertyValues { public void applyToSystemProperties(Runnable action) { applyToSystemProperties(() -> { action.run(); - return null; + return new Object(); }); } @@ -332,7 +332,7 @@ public final class TestPropertyValues { this.value = value; } - public void addTo(Map properties) { + public void addTo(Map properties) { properties.put(this.name, this.value); }