Hi,

I have a spring web app with tests which start a jetty web server. The code looks something like:

// import org.eclipse.jetty.server.*
// import org.eclipse.jetty.webapp.*

       final Server server = new Server(port);

        final WebAppContext context = new WebAppContext();
        context.setContextPath(contextPath);
        context.setResourceBase(new File("src/main/webapp").getAbsolutePath());
        context.setDescriptor(new File("src/main/webapp/WEB-INF/web.xml").getAbsolutePath());
        context.setParentLoaderPriority(true);
        context.setServer(server);
        server.setHandler(context);
        server.start
        // Interact with server and so spring as well here.
        server.stop/join/destroy

This all works well, except for when I enable parallel testing. With parallel testing (so multiple jetty servers may be running at a time and so spring will be called under the the web server at the same time) enabled I start to get attempted duplicate class definitions:

Caused by: java.lang.LinkageError: loader 'app' attempted duplicate class definition for com.AccountV1ApiCalls$$FastClassBySpringCGLIB$$6bb614f1. (com.AccountV1ApiCalls$$FastClassBySpringCGLIB$$6bb614f1 is in unnamed module of loader 'app')
    at java.lang.ClassLoader.defineClass1(Native Method) ~[?:?]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:1017) ~[?:?]
    at jdk.internal.reflect.GeneratedMethodAccessor101.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:523) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    ... 108 more

I can't imagine that it is expected that spring would be thread-unsafe.

Comment From: jhoeller

The problematic part here is that those parallel tests operate with independently managed Spring ApplicationContexts against the same ClassLoader. We don't have a common lock between those independent contexts, and the expectation of the ClassLoader being under the application's isolated control is broken as well.

I'd recommend independent ClassLoaders for each individual test bootstrap, to be passed to ConfigurableApplicationContext.setClassLoader. Even an empty URLClassLoader pointing to the common parent should provide enough isolation for newly defined classes here.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

Comment From: LukeButters

I think that works, other issues now show up.

Should this be done by default? I guess the assumption is most people are not running tests in parallel with spring, so most people wont run into this.