Skip to content

Commit 6dabfb4

Browse files
committed
GH-191 - Prevent premature access of ApplicationContext from ParameterResolver implementations.
We now avoid accessing the ApplicationContext from a BeforeAllCallback as this might cause the context initialization before other extensions had time to kick in.
1 parent c111e41 commit 6dabfb4

File tree

3 files changed

+42
-43
lines changed

3 files changed

+42
-43
lines changed

spring-modulith-test/src/main/java/org/springframework/modulith/test/PublishedEventsParameterResolver.java

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.function.Function;
1919

2020
import org.junit.jupiter.api.extension.AfterEachCallback;
21-
import org.junit.jupiter.api.extension.BeforeAllCallback;
2221
import org.junit.jupiter.api.extension.ExtensionContext;
2322
import org.junit.jupiter.api.extension.ParameterContext;
2423
import org.junit.jupiter.api.extension.ParameterResolver;
@@ -35,7 +34,7 @@
3534
*
3635
* @author Oliver Drotbohm
3736
*/
38-
class PublishedEventsParameterResolver implements ParameterResolver, BeforeAllCallback, AfterEachCallback {
37+
class PublishedEventsParameterResolver implements ParameterResolver, AfterEachCallback {
3938

4039
private static final boolean ASSERT_J_PRESENT = ClassUtils.isPresent("org.assertj.core.api.Assert",
4140
PublishedEventsParameterResolver.class.getClassLoader());
@@ -51,32 +50,6 @@ class PublishedEventsParameterResolver implements ParameterResolver, BeforeAllCa
5150
this.lookup = supplier;
5251
}
5352

54-
/*
55-
* (non-Javadoc)
56-
* @see org.junit.jupiter.api.extension.BeforeAllCallback#beforeAll(org.junit.jupiter.api.extension.ExtensionContext)
57-
*/
58-
@Override
59-
public void beforeAll(ExtensionContext extensionContext) {
60-
61-
ApplicationContext context = lookup.apply(extensionContext);
62-
63-
if (!(context instanceof AbstractApplicationContext aac)) {
64-
throw new IllegalStateException();
65-
}
66-
67-
listener = aac.getApplicationListeners().stream()
68-
.filter(ThreadBoundApplicationListenerAdapter.class::isInstance)
69-
.map(ThreadBoundApplicationListenerAdapter.class::cast)
70-
.findFirst()
71-
.orElseGet(() -> {
72-
73-
var adapter = new ThreadBoundApplicationListenerAdapter();
74-
aac.addApplicationListener(adapter);
75-
76-
return adapter;
77-
});
78-
}
79-
8053
/*
8154
* (non-Javadoc)
8255
* @see org.junit.jupiter.api.extension.ParameterResolver#supportsParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)
@@ -105,18 +78,47 @@ public PublishedEvents resolveParameter(ParameterContext parameterContext, Exten
10578
? new DefaultAssertablePublishedEvents()
10679
: new DefaultPublishedEvents();
10780

81+
initializeListener(extensionContext);
10882
listener.registerDelegate(publishedEvents);
10983

11084
return publishedEvents;
11185
}
11286

87+
private void initializeListener(ExtensionContext extensionContext) {
88+
89+
if (listener != null) {
90+
return;
91+
}
92+
93+
ApplicationContext context = lookup.apply(extensionContext);
94+
95+
if (!(context instanceof AbstractApplicationContext aac)) {
96+
throw new IllegalStateException();
97+
}
98+
99+
listener = aac.getApplicationListeners().stream()
100+
.filter(ThreadBoundApplicationListenerAdapter.class::isInstance)
101+
.map(ThreadBoundApplicationListenerAdapter.class::cast)
102+
.findFirst()
103+
.orElseGet(() -> {
104+
105+
var adapter = new ThreadBoundApplicationListenerAdapter();
106+
aac.addApplicationListener(adapter);
107+
108+
return adapter;
109+
});
110+
}
111+
113112
/*
114113
* (non-Javadoc)
115114
* @see org.junit.jupiter.api.extension.AfterEachCallback#afterEach(org.junit.jupiter.api.extension.ExtensionContext)
116115
*/
117116
@Override
118117
public void afterEach(ExtensionContext context) {
119-
listener.unregisterDelegate();
118+
119+
if (listener != null) {
120+
listener.unregisterDelegate();
121+
}
120122
}
121123

122124
/**

spring-modulith-test/src/main/java/org/springframework/modulith/test/ScenarioParameterResolver.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.modulith.test;
1717

18-
import org.junit.jupiter.api.extension.BeforeAllCallback;
18+
import org.junit.jupiter.api.extension.AfterEachCallback;
1919
import org.junit.jupiter.api.extension.ExtensionContext;
2020
import org.junit.jupiter.api.extension.ParameterContext;
2121
import org.junit.jupiter.api.extension.ParameterResolutionException;
@@ -30,7 +30,7 @@
3030
*
3131
* @author Oliver Drotbohm
3232
*/
33-
class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback {
33+
class ScenarioParameterResolver implements ParameterResolver, AfterEachCallback {
3434

3535
private static final String MISSING_TRANSACTION_TEMPLATE = "To use a Scenario in an integration test you need to define a bean of type TransactionTemplate! Please check your ApplicationContext setup.";
3636

@@ -43,6 +43,15 @@ public ScenarioParameterResolver() {
4343
this.delegate = new PublishedEventsParameterResolver();
4444
}
4545

46+
/*
47+
* (non-Javadoc)
48+
* @see org.junit.jupiter.api.extension.AfterEachCallback#afterEach(org.junit.jupiter.api.extension.ExtensionContext)
49+
*/
50+
@Override
51+
public void afterEach(ExtensionContext context) throws Exception {
52+
delegate.afterEach(context);
53+
}
54+
4655
/*
4756
* (non-Javadoc)
4857
* @see org.junit.jupiter.api.extension.ParameterResolver#supportsParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)
@@ -56,15 +65,6 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon
5665
return Scenario.class.isAssignableFrom(type);
5766
}
5867

59-
/*
60-
* (non-Javadoc)
61-
* @see org.junit.jupiter.api.extension.BeforeAllCallback#beforeAll(org.junit.jupiter.api.extension.ExtensionContext)
62-
*/
63-
@Override
64-
public void beforeAll(ExtensionContext context) throws Exception {
65-
delegate.beforeAll(context);
66-
}
67-
6868
/*
6969
* (non-Javadoc)
7070
* @see org.junit.jupiter.api.extension.ParameterResolver#resolveParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)

spring-modulith-test/src/test/java/org/springframework/modulith/test/PublishedEventsParameterResolverUnitTests.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ void createsThreadBoundPublishedEvents() throws Exception {
5656
PublishedEventsParameterResolver resolver = new PublishedEventsParameterResolver(__ -> context);
5757
context.refresh();
5858

59-
resolver.beforeAll(null);
60-
6159
Map<String, PublishedEvents> allEvents = new ConcurrentHashMap<>();
6260
List<String> keys = Arrays.asList("first", "second", "third");
6361
CountDownLatch latch = new CountDownLatch(3);
@@ -75,7 +73,6 @@ void createsThreadBoundPublishedEvents() throws Exception {
7573
latch.countDown();
7674

7775
}).start();
78-
7976
}
8077

8178
latch.await(50, TimeUnit.MILLISECONDS);

0 commit comments

Comments
 (0)