Closed
Description
Phil Webb opened SPR-16902 and commented
Spring Boot recently upgrade to Framework 5.1 SNAPSHOTS and we're now seeing "loader attempted duplicate class definition" errors with our devtools integration tests on Java 9 and Java 10 (Java 8 is fine).
Here's an example of a failing build.
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class org.springframework.boot.autoconfigure.http.HttpMessageConverters: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.LinkageError-->loader (instance of jdk/internal/loader/ClassLoaders$AppClassLoader): attempted duplicate class definition for name: "org/springframework/boot/autoconfigure/http/HttpMessageConverters$$EnhancerBySpringCGLIB$$1d90bff9"
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:208) ~[spring-aop-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) ~[spring-aop-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(ContextAnnotationAutowireCandidateResolver.java:117) ~[spring-context-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(ContextAnnotationAutowireCandidateResolver.java:52) ~[spring-context-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:197) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1276) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1133) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) ~[spring-beans-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
... 34 common frames omitted
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.LinkageError-->loader (instance of jdk/internal/loader/ClassLoaders$AppClassLoader): attempted duplicate class definition for name: "org/springframework/boot/autoconfigure/http/HttpMessageConverters$$EnhancerBySpringCGLIB$$1d90bff9"
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:502) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:359) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:106) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:104) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:315) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:416) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:58) ~[spring-aop-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) ~[spring-aop-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
... 45 common frames omitted
Caused by: java.lang.LinkageError: loader (instance of jdk/internal/loader/ClassLoaders$AppClassLoader): attempted duplicate class definition for name: "org/springframework/boot/autoconfigure/http/HttpMessageConverters$$EnhancerBySpringCGLIB$$1d90bff9"
at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
at java.base/java.lang.System$2.defineClass(System.java:2120) ~[na:na]
at java.base/java.lang.invoke.MethodHandles$Lookup.defineClass(MethodHandles.java:964) ~[na:na]
at java.base/jdk.internal.reflect.GeneratedMethodAccessor25.invoke(Unknown Source) ~[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:564) ~[na:na]
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:498) ~[spring-core-5.1.0.BUILD-SNAPSHOT.jar:5.1.0.BUILD-SNAPSHOT]
... 59 common frames omitted
The same tests on Spring Boot 2.0 (which uses Framework 5.0) pass fine on Java 8, 9 and 10.
My guess is this relates to #20414 and is probably caused by our slightly unusual DevTools classloader arrangement.
Affects: 5.1 RC1
Issue Links:
- MethodHandles.Lookup.defineClass for CGLIB class definition purposes [SPR-15859] #20414 MethodHandles.Lookup.defineClass for CGLIB class definition purposes
- Revise ClassUtils.isPresent for exposing resolution exceptions in jlinked modules [SPR-17018] #21556 Revise ClassUtils.isPresent for exposing resolution exceptions in jlinked modules
Referenced from: commits 6887802