Wrong proxy generation order during AOT for classes with `ScopedProxyMode.TARGET_CLASS` and advisors
OlgaMaciaszek opened this issue · 3 comments
Initially reported in spring-cloud/spring-cloud-commons#1211.
When a class has both a scope with ScopedProxyMode.TARGET_CLASS
mode and an advisor register for it, the predetermineBeanTypes(...)
call within refreshForAotProcessing(...)
in ContextAotProcessor
leads to the creation of proxies and corresponding files in wrong order when scopedTarget.[actualBeanName]
bean definitions are processed. As part of this process, interceptors for that bean are searched for within the AbstractAdvisorAutoProxyCreator
's getAdvicesAndAdvisorsForBean(..)
method, which recognises the existence of an aspect. Since interceptors are found, the type determination will be done for proxy type, but in order to verify the relevant proxy type, actual proxy creation is attempted through a call to createProxyClass()
. That’s when the CGLIB proxy with corresponding file indexed $$0
, which seems to be the root of the problem. (Maybe there would be a way to reason about the proxy type without finalising the proxy creation?). The proxy is later on created for the [actualBeanName]
bean, indexed with $$1
. However, at runtime it's the [actualBeanName]
that gets processed before, along with the corresponding proxy creation, triggering the proxy creation for scopedTarget.[actualBeanName]
after that. Since the order and indexing of the proxies is reversed, the wrong one gets picked at runtime resulting in exception.
You can find a user-provided sample here: https://github.com/justin-tay/spring-boot-refresh-aspect-issue and it's analysis here.
I can reproduce by building a repackaged archive with AOT optimizations and not even enabling them. The linked report specifies that -Dspring.aot.enabled=true
should be provided which is not necessary for me. Wondering if that's an oversight in the report or something that wasn't discovered until now.
This seems to be a side effect of calling SmartInstantiationAwareBeanPostProcessor#determineBeanType
too early. We're investigating.
Right, it does also fail without setting -Dspring.aot.enabled=true
. I think this has not been verified previously.