Description
We are in the process of making our application run on Java 17 using Spring Boot 2.6 and Spring Framework 5.3.
We have a test setup where we register our web endpoints in different servlets. We do this by using the ServletRegistrationBean
from Spring Boot and create a DispatcherServlet
using an AnnotationConfigWebApplicationContext
.
A linkage error occurs when we try to have different tests with different configuration, i.e. each test will create its own application context.
I have created a small project showcasing this problem (https://github.com/filiphr/spring-java-17-duplicate-class-definition).
The main error is
Caused by: java.lang.LinkageError: loader 'app' attempted duplicate class definition for com.example.rest.DemoService$$EnhancerBySpringCGLIB$$8972e13d. (com.example.rest.DemoService$$EnhancerBySpringCGLIB$$8972e13d is in unnamed module of loader 'app')
at java.base/java.lang.ClassLoader.defineClass0(Native Method) ~[na:na]
at java.base/java.lang.System$2.defineClass(System.java:2307) ~[na:na]
at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2439) ~[na:na]
at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2416) ~[na:na]
at java.base/java.lang.invoke.MethodHandles$Lookup.defineClass(MethodHandles.java:1843) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:577) ~[spring-core-5.3.15.jar:5.3.15]
... 135 common frames omitted
I have also found #25940 which looks like it has the same cause for the problem. However, I believe that my example is slightly less complicated.
Is it possible for Spring to do something and not create duplicate class definitions and create unique class names per application context as commented by @iherasymenko in #25940 (comment)?