You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GraalVM native-image only supports JDK dynamic proxies when configured explicitly on interfaces.
For proxies on classes, typically created at runtime with CGLIB on the JVM, there is a need to create such proxies Ahead-Of-Time. That's what @aclement did in Spring Native:
Just a bit more context. I could have built my own proxy generation but it would have taken a while and I wasn't in a position to easily test it rigorously for all spring use cases. So I leveraged #1283 which replaced CGLIB with byte buddy because I knew that was passing the tests, and it would give me an easier route to pushing proxy generation to being something I could drive at build time rather than runtime. It had mechanisms for easily grabbing the bytecode for the proxy, and total control over the proxy naming (because when looking them up at runtime it had to exactly match what was created earlier).
Importantly it was also generating a more optimal proxy that was using less of the generated support classes for invoking some methods. For 'well known' interfaces that the proxy was implementing it was directly wiring up the invocations. Whereas CGLIB was using a general approach for all methods, leading to lots of new classes. (However, hand crafting could have also performed these optimizations, obviously).
The current version was definitely constructed as a building block. Ideally the necessary proxies could be more inferred rather than the user trying to work out what set of 'bits' they need to supply for proxy hints, or discovering it by trial and error when running the system is printing out the required hints.
Related topic : Spring Native we currently relies on Hibernate Build-time enhancement to perform Hibernate bytecode manipulation at build time. I mention that because:
It could be interesting to see how they implemented that.
This seems not super actively maintained (for example, no Gradle Kotlin DSL support if I remember correctly).
Using that imply painful additional build configuration, we may be interested by a more integrated approach.
There is an initial commit coming to main now: This includes runtime storing of generated classes to a directory specified by the "cglib.generatedClasses" system property, to be picked up by the build process for further inclusion in a jar file (and ultimately in a native image). We also avoid lazy CGLIB fast-class generation now and replace the generated Enhancer and MethodWrapper key classes with equivalent record types. Last but not least, this introduces support for early type determination in InstantiationStrategy, AopProxy and SmartInstantiationAwareBeanPostProcessor - in order to trigger CGLIB class generation in refreshForAotProcessing (through early determineBeanType calls for bean definitions).
Activity
aclement commentedon Feb 28, 2022
Just a bit more context. I could have built my own proxy generation but it would have taken a while and I wasn't in a position to easily test it rigorously for all spring use cases. So I leveraged #1283 which replaced CGLIB with byte buddy because I knew that was passing the tests, and it would give me an easier route to pushing proxy generation to being something I could drive at build time rather than runtime. It had mechanisms for easily grabbing the bytecode for the proxy, and total control over the proxy naming (because when looking them up at runtime it had to exactly match what was created earlier).
Importantly it was also generating a more optimal proxy that was using less of the generated support classes for invoking some methods. For 'well known' interfaces that the proxy was implementing it was directly wiring up the invocations. Whereas CGLIB was using a general approach for all methods, leading to lots of new classes. (However, hand crafting could have also performed these optimizations, obviously).
The current version was definitely constructed as a building block. Ideally the necessary proxies could be more inferred rather than the user trying to work out what set of 'bits' they need to supply for proxy hints, or discovering it by trial and error when running the system is printing out the required hints.
aclement commentedon Feb 28, 2022
The commit encompassing all these changes in spring-native is spring-attic/spring-native@af0e804
sdeleuze commentedon Mar 2, 2022
Related topic : Spring Native we currently relies on Hibernate Build-time enhancement to perform Hibernate bytecode manipulation at build time. I mention that because:
Maybe a point to discuss with @mp911de, @schauder and @christophstrobl.
Add support for @transactional in native images
Add support for @transactional in native images
jhoeller commentedon Aug 10, 2022
There is an initial commit coming to main now: This includes runtime storing of generated classes to a directory specified by the "cglib.generatedClasses" system property, to be picked up by the build process for further inclusion in a jar file (and ultimately in a native image). We also avoid lazy CGLIB fast-class generation now and replace the generated Enhancer and MethodWrapper key classes with equivalent record types. Last but not least, this introduces support for early type determination in InstantiationStrategy, AopProxy and SmartInstantiationAwareBeanPostProcessor - in order to trigger CGLIB class generation in refreshForAotProcessing (through early determineBeanType calls for bean definitions).
Fix StepScopeProxyTargetClassOverrideIntegrationTests
Support for pre-generated CGLIB proxy classes (in AOT scenarios)