Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reintroduce FastClass in CGLIB class names for @Configuration classes #31272

Closed
sbrannen opened this issue Sep 19, 2023 · 1 comment
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Milestone

Comments

@sbrannen
Copy link
Member

sbrannen commented Sep 19, 2023

While investigating the cause of the regression reported in #31238, I noticed that Spring Framework makes multiple attempts to create CGLIB proxy classes for @Configuration classes before actually instantiating the proxy instance.

For example, if you run the transactionProxyIsCreated() test method in EnableTransactionManagementTests and introduce tracing for proxy classes generated, you will see something similar to the following.

loadClass: org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$0
loadClass: org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$1
defineClass: class org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$1
loadClass: org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$2
defineClass: class org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$2
defineClass: class org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$0
>>>> class org.springframework.transaction.annotation.EnableTransactionManagementTests$TxManagerConfig$$SpringCGLIB$$0

The last line (>>>> class ...) denotes the actual generated class ($TxManagerConfig$$SpringCGLIB$$0) that was used to instantiate the proxy for the TxManagerConfig configuration class; however, $TxManagerConfig$$SpringCGLIB$$1 and $TxManagerConfig$$SpringCGLIB$$2 were also created in the interim even though they were not used in the end.

In addition, all of the generated proxy classes for a given @Configuration class are recorded by Spring AOT and stored in a GraalVM native image.

Ideally, those interim classes should not be generated. Thus, it appears that there is an issue with cache key, and this appears to be a regression.


The following can be used to track which proxy classes are loaded.

ReflectUtils.setLoadedClassHandler(clazz -> System.out.println("loadClass: " + clazz.getName()));
@sbrannen sbrannen added type: regression A bug that is also a regression in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing labels Sep 19, 2023
@sbrannen sbrannen added this to the 6.0.13 milestone Sep 19, 2023
@sbrannen sbrannen self-assigned this Sep 19, 2023
@sbrannen
Copy link
Member Author

sbrannen commented Sep 25, 2023

After thorough analysis, I have determined that there are no duplicate CGLIB proxy classes generated for @Configuration classes.

If a @Configuration class does not contain any @Bean methods, only a single class is generated by CGLIB, and that class is the proxy class.

On the other hand, if a @Configuration class contains @Bean methods, 2 additional classes are generated by CGLIB. These are FastClass implementations that are required to support super.myBeanMethod() invocations which cannot be achieved via standard JDK reflection.

6.0.x

When running my test on 6.0.x, it appears that 3 proxy classes are generated.

org.example.AppConfig$$SpringCGLIB$$0
org.example.AppConfig$$SpringCGLIB$$1
org.example.AppConfig$$SpringCGLIB$$2

5.3.x

When running the same test on 5.3.x, the generated class names provide a better picture of what's going on.

org.example.AppConfig$$EnhancerBySpringCGLIB$$fd7e9baa
org.example.AppConfig$$FastClassBySpringCGLIB$$3fec86e
org.example.AppConfig$$EnhancerBySpringCGLIB$$fd7e9baa$$FastClassBySpringCGLIB$$82534900

In light of that, I am repurposing this issue to investigate whether we can reintroduce FastClass into the generated class names (when appropriate) while retaining the reproducibility of generated proxy class names that was introduced in commit b31a158.

@sbrannen sbrannen added type: enhancement A general enhancement and removed type: regression A bug that is also a regression labels Sep 25, 2023
@sbrannen sbrannen changed the title Duplicate CGLIB proxy classes are generated for @Configuration classes Reintroduce FastClass in CGLIB class names for @Configuration classes Sep 25, 2023
sbrannen added a commit that referenced this issue Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

1 participant