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.
This commit is contained in:
@@ -18,7 +18,6 @@ package org.springframework.modulith.test;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
@@ -35,7 +34,7 @@ import org.springframework.util.ClassUtils;
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class PublishedEventsParameterResolver implements ParameterResolver, BeforeAllCallback, AfterEachCallback {
|
||||
class PublishedEventsParameterResolver implements ParameterResolver, AfterEachCallback {
|
||||
|
||||
private static final boolean ASSERT_J_PRESENT = ClassUtils.isPresent("org.assertj.core.api.Assert",
|
||||
PublishedEventsParameterResolver.class.getClassLoader());
|
||||
@@ -51,32 +50,6 @@ class PublishedEventsParameterResolver implements ParameterResolver, BeforeAllCa
|
||||
this.lookup = supplier;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.BeforeAllCallback#beforeAll(org.junit.jupiter.api.extension.ExtensionContext)
|
||||
*/
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext extensionContext) {
|
||||
|
||||
ApplicationContext context = lookup.apply(extensionContext);
|
||||
|
||||
if (!(context instanceof AbstractApplicationContext aac)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
listener = aac.getApplicationListeners().stream()
|
||||
.filter(ThreadBoundApplicationListenerAdapter.class::isInstance)
|
||||
.map(ThreadBoundApplicationListenerAdapter.class::cast)
|
||||
.findFirst()
|
||||
.orElseGet(() -> {
|
||||
|
||||
var adapter = new ThreadBoundApplicationListenerAdapter();
|
||||
aac.addApplicationListener(adapter);
|
||||
|
||||
return adapter;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.ParameterResolver#supportsParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)
|
||||
@@ -105,18 +78,47 @@ class PublishedEventsParameterResolver implements ParameterResolver, BeforeAllCa
|
||||
? new DefaultAssertablePublishedEvents()
|
||||
: new DefaultPublishedEvents();
|
||||
|
||||
initializeListener(extensionContext);
|
||||
listener.registerDelegate(publishedEvents);
|
||||
|
||||
return publishedEvents;
|
||||
}
|
||||
|
||||
private void initializeListener(ExtensionContext extensionContext) {
|
||||
|
||||
if (listener != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationContext context = lookup.apply(extensionContext);
|
||||
|
||||
if (!(context instanceof AbstractApplicationContext aac)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
listener = aac.getApplicationListeners().stream()
|
||||
.filter(ThreadBoundApplicationListenerAdapter.class::isInstance)
|
||||
.map(ThreadBoundApplicationListenerAdapter.class::cast)
|
||||
.findFirst()
|
||||
.orElseGet(() -> {
|
||||
|
||||
var adapter = new ThreadBoundApplicationListenerAdapter();
|
||||
aac.addApplicationListener(adapter);
|
||||
|
||||
return adapter;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.AfterEachCallback#afterEach(org.junit.jupiter.api.extension.ExtensionContext)
|
||||
*/
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) {
|
||||
listener.unregisterDelegate();
|
||||
|
||||
if (listener != null) {
|
||||
listener.unregisterDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.modulith.test;
|
||||
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
@@ -30,7 +30,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback {
|
||||
class ScenarioParameterResolver implements ParameterResolver, AfterEachCallback {
|
||||
|
||||
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.";
|
||||
|
||||
@@ -43,6 +43,15 @@ class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback
|
||||
this.delegate = new PublishedEventsParameterResolver();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.AfterEachCallback#afterEach(org.junit.jupiter.api.extension.ExtensionContext)
|
||||
*/
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) throws Exception {
|
||||
delegate.afterEach(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.ParameterResolver#supportsParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)
|
||||
@@ -56,15 +65,6 @@ class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback
|
||||
return Scenario.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.BeforeAllCallback#beforeAll(org.junit.jupiter.api.extension.ExtensionContext)
|
||||
*/
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
delegate.beforeAll(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.junit.jupiter.api.extension.ParameterResolver#resolveParameter(org.junit.jupiter.api.extension.ParameterContext, org.junit.jupiter.api.extension.ExtensionContext)
|
||||
|
||||
@@ -56,8 +56,6 @@ class PublishedEventsParameterResolverUnitTests {
|
||||
PublishedEventsParameterResolver resolver = new PublishedEventsParameterResolver(__ -> context);
|
||||
context.refresh();
|
||||
|
||||
resolver.beforeAll(null);
|
||||
|
||||
Map<String, PublishedEvents> allEvents = new ConcurrentHashMap<>();
|
||||
List<String> keys = Arrays.asList("first", "second", "third");
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
@@ -75,7 +73,6 @@ class PublishedEventsParameterResolverUnitTests {
|
||||
latch.countDown();
|
||||
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
latch.await(50, TimeUnit.MILLISECONDS);
|
||||
|
||||
Reference in New Issue
Block a user