Skip to content

Commit a2ef2c9

Browse files
committed
Refined check for NoClassDefFoundError in getTestExecutionListeners()
Issue: SPR-11804 (cherry picked from commit 41ed228)
1 parent 1bbc032 commit a2ef2c9

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

spring-test/src/main/java/org/springframework/test/context/TestContextManager.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.commons.logging.Log;
2828
import org.apache.commons.logging.LogFactory;
2929

30+
import org.springframework.beans.BeanInstantiationException;
3031
import org.springframework.beans.BeanUtils;
3132
import org.springframework.core.annotation.AnnotationAttributes;
3233
import org.springframework.util.Assert;
@@ -74,10 +75,10 @@
7475
public class TestContextManager {
7576

7677
private static final String[] DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES = new String[] {
77-
"org.springframework.test.context.web.ServletTestExecutionListener",
78-
"org.springframework.test.context.support.DependencyInjectionTestExecutionListener",
79-
"org.springframework.test.context.support.DirtiesContextTestExecutionListener",
80-
"org.springframework.test.context.transaction.TransactionalTestExecutionListener" };
78+
"org.springframework.test.context.web.ServletTestExecutionListener",
79+
"org.springframework.test.context.support.DependencyInjectionTestExecutionListener",
80+
"org.springframework.test.context.support.DirtiesContextTestExecutionListener",
81+
"org.springframework.test.context.transaction.TransactionalTestExecutionListener" };
8182

8283
private static final Log logger = LogFactory.getLog(TestContextManager.class);
8384

@@ -194,24 +195,21 @@ private TestExecutionListener[] retrieveTestExecutionListeners(Class<?> clazz) {
194195
// Traverse the class hierarchy...
195196
while (descriptor != null) {
196197
Class<?> declaringClass = descriptor.getDeclaringClass();
197-
198198
AnnotationAttributes annAttrs = descriptor.getAnnotationAttributes();
199199
if (logger.isTraceEnabled()) {
200-
logger.trace(String.format(
201-
"Retrieved @TestExecutionListeners attributes [%s] for declaring class [%s].", annAttrs,
202-
declaringClass));
200+
logger.trace(String.format("Retrieved @TestExecutionListeners attributes [%s] for declaring class [%s].",
201+
annAttrs, declaringClass));
203202
}
204203

205-
Class<? extends TestExecutionListener>[] valueListenerClasses = (Class<? extends TestExecutionListener>[]) annAttrs.getClassArray("value");
206-
Class<? extends TestExecutionListener>[] listenerClasses = (Class<? extends TestExecutionListener>[]) annAttrs.getClassArray("listeners");
204+
Class<? extends TestExecutionListener>[] valueListenerClasses =
205+
(Class<? extends TestExecutionListener>[]) annAttrs.getClassArray("value");
206+
Class<? extends TestExecutionListener>[] listenerClasses =
207+
(Class<? extends TestExecutionListener>[]) annAttrs.getClassArray("listeners");
207208
if (!ObjectUtils.isEmpty(valueListenerClasses) && !ObjectUtils.isEmpty(listenerClasses)) {
208-
String msg = String.format(
209-
"Class [%s] has been configured with @TestExecutionListeners' 'value' [%s] "
210-
+ "and 'listeners' [%s] attributes. Use one or the other, but not both.",
211-
declaringClass, ObjectUtils.nullSafeToString(valueListenerClasses),
212-
ObjectUtils.nullSafeToString(listenerClasses));
213-
logger.error(msg);
214-
throw new IllegalStateException(msg);
209+
throw new IllegalStateException(String.format("Class [%s] configured with @TestExecutionListeners' " +
210+
"'value' [%s] and 'listeners' [%s] attributes. Use one or the other, but not both.",
211+
declaringClass, ObjectUtils.nullSafeToString(valueListenerClasses),
212+
ObjectUtils.nullSafeToString(listenerClasses)));
215213
}
216214
else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
217215
listenerClasses = valueListenerClasses;
@@ -220,22 +218,31 @@ else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
220218
if (listenerClasses != null) {
221219
classesList.addAll(0, Arrays.<Class<? extends TestExecutionListener>> asList(listenerClasses));
222220
}
223-
224221
descriptor = (annAttrs.getBoolean("inheritListeners") ? MetaAnnotationUtils.findAnnotationDescriptor(
225222
descriptor.getRootDeclaringClass().getSuperclass(), annotationType) : null);
226223
}
227224
}
228225

229226
List<TestExecutionListener> listeners = new ArrayList<TestExecutionListener>(classesList.size());
230227
for (Class<? extends TestExecutionListener> listenerClass : classesList) {
228+
NoClassDefFoundError ncdfe = null;
231229
try {
232230
listeners.add(BeanUtils.instantiateClass(listenerClass));
233231
}
234232
catch (NoClassDefFoundError err) {
233+
ncdfe = err;
234+
}
235+
catch (BeanInstantiationException ex) {
236+
if (ex.getCause() instanceof NoClassDefFoundError) {
237+
ncdfe = (NoClassDefFoundError) ex.getCause();
238+
}
239+
}
240+
if (ncdfe != null) {
235241
if (logger.isInfoEnabled()) {
236-
logger.info(String.format("Could not instantiate TestExecutionListener class [%s]. " +
242+
logger.info(String.format("Could not instantiate TestExecutionListener [%s]. " +
237243
"Specify custom listener classes or make the default listener classes " +
238-
"(and their dependencies) available.", listenerClass.getName()));
244+
"(and their required dependencies) available. Offending class: [%s]",
245+
listenerClass.getName(), ncdfe.getMessage()));
239246
}
240247
}
241248
}

0 commit comments

Comments
 (0)