Skip to content

aop:scoped-proxy may fail with LinkageError: loader attempted duplicate class definition for name [SPR-11398] #16025

@spring-projects-issues

Description

@spring-projects-issues

Piotr Findeisen opened SPR-11398 and commented

When using:

  • cglib 2.2 directly
  • spring 3.2.5 (which wraps cglib 3.0) and spring's <aop:scoped-proxy/> feature

it possible to run into

java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader):
   attempted  duplicate class definition for name: "$java/lang/Object$$FastClassByCGLIB$$3f697993"

Full stacktrace:

org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
	at org.springframework.cglib.reflect.FastClass$Generator.create(FastClass.java:64)
	at org.springframework.cglib.proxy.MethodProxy.helper(MethodProxy.java:121)
	at org.springframework.cglib.proxy.MethodProxy.init(MethodProxy.java:74)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:202)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:132)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:120)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
	at com.MyBean$$EnhancerByCGLIB$$f1fad224.toString(<generated>)
	at com.MyTest.testBeanWithAopScopedProxy(SpringAndCglibTest.java:122)
....
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
	... 36 more
Caused by: java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "$java/lang/Object$$FastClassByCGLIB$$3f697993"
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	... 41 more
Attempt at analysis

As far as I can understand, this seems to be caused by class naming conflict between CGLIB 2.2 and Spring-repackaged CGLIB.

CGLIB's DefaultNamingPolicy solves name collisions using sort of "already used set", but obviously there are two such sets -- one CGLIB's and another Spring-CGLIB's -- so name collisions cannot be avoided and class generation fails.

Notes

This is not only about probabilistic name clash. There seems to be nothing preventing Spring-CGLIB unconsciously re-using classes generated by non-Spring-CGLIB, which may be "programmed" with different behavior than desired.

Proposed solution

Spring is already using non-default prefix ("org.springframework.cglib.empty.Object", see DefaultNamingPolicy.getClassName), but this is not enough, since prefix is not used if provided explicitly.

  • Spring-repackaged CGLIB could have DefaultNamingPolicy.getTag() function changed to return something else than "ByCGLIB"
  • OR DefaultNamingPolicy could be called with different 'source' -- see initialization of org.springframework.cglib.reflect.FastClass.SOURCE

Affects: 3.2.5, 4.0 GA

Issue Links:

Backported to: 3.2.8

0 votes, 5 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: 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