Skip to content

Handle NoClassDefFoundError for TestExecutionListeners consistently in the TestContext framework [SPR-11347] #15971

Closed
@spring-projects-issues

Description

@spring-projects-issues

Gary Russell opened SPR-11347 and commented

Background

Changes introduced in #15964 cause subclasses of abstract base test classes (i.e. AbstractJUnit4SpringContextTests and AbstractTestNGSpringContextTests) in a non-web environment to fail with java.lang.NoClassDefFoundError: javax/servlet/ServletContext.

There are a number of such test classes in Spring Integration that now break due to #15964.


Analysis

The fact that abstract base test classes pull in ServletTestExecutionListener is not problematic on its own (at least not with regard to the intended behavior of the TestContext framework's support for default listeners). Rather, the issue here is that a NoClassDefFoundError is handled differently for implicit default listeners (i.e., listeners not declared via @TestExecutionListeners) and listeners explicitly declared via @TestExecutionListeners.

The following code snippet from TestContextManager.retrieveTestExecutionListeners() represents the status quo.

try {
	listeners.add(BeanUtils.instantiateClass(listenerClass));
}
catch (NoClassDefFoundError err) {
	if (defaultListeners) {
		if (logger.isDebugEnabled()) {
			logger.debug("Could not instantiate default TestExecutionListener class ["
					+ listenerClass.getName()
					+ "]. Specify custom listener classes or make the default listener classes available.");
		}
	}
	else {
		throw err;
	}
}

In the case of AbstractJUnit4SpringContextTests and AbstractTestNGSpringContextTests, the ServletTestExecutionListener is explicitly declared via @TestExecutionListeners as a convenience for the developer; however, ServletTestExecutionListener is still considered a default from the perspective of the end user. The try-catch block in retrieveTestExecutionListeners() should therefore be amended to work as intended for both implicit and explicit defaults.


Deliverables

  1. Refactor the try-catch block in TestContextManager.retrieveTestExecutionListeners() as follows:
    1. Always swallow the NoClassDefFoundError.
    2. Change log level from DEBUG to INFO.
    3. Do not include the stack trace with log output.

Affects: 4.0.1

Issue Links:

Referenced from: commits fb12e23, c1569d7

Backported to: 3.2.7

0 votes, 6 watchers

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulestatus: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions