Latest Spring Security 6.2.3 breaks AOT for native image (I've been asked to recreate this issue here).
Config: 1. Spring Boot 3.2.4 2. Spring 6.1.5 3. Spring Security 6.2.3. spring-security-oauth2-authorization-server 1.2.3 4. GraalVM CE 21.0.2 5. native-maven-plugin 0.10.1
If I uncomment Transactional annotation in CheckRolesLdapAuthenticationProvider (see reproducer) I got the following:
Caused by: java.lang.UnsupportedOperationException: CGLIB runtime enhancement not supported on native image. Make sure to include a pre-generated class on the classpath instead: io.imi.aot_test.auth.CheckRolesLdapAuthenticationProvider$$SpringCGLIB$$1
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363) ~[aot_test:6.1.5]
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:575) ~[na:na]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:107) ~[na:na]
at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) ~[na:na]
at java.base@21.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[aot_test:na]
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57) ~[na:na]
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[na:na]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) ~[na:na]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317) ~[aot_test:6.1.5]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562) ~[na:na]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407) ~[na:na]
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:62) ~[na:na]
at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:218) ~[aot_test:6.1.5]
... 79 common frames omitted
Full log: aot-error.log
There are 2 classes generated CheckRolesLdapAuthenticationProvider$$SpringCGLIB$$0 and CheckRolesLdapAuthenticationProvider$$SpringCGLIB$$1 which we could find in both reflection-config.json/predefined-classes-config.json which I suppose is wrong.
There is no error without Transactional.
Reproducer: https://github.com/nnl-1/SpringBoot3AotTransactionalReproducer
Thank you!
Comment From: marcusdacoregio
Hi @nnl-1, thanks for the report.
Have you confirmed that the same code works with Spring Security 6.2.2?
Comment From: nnl-1
Hi @nnl-1, thanks for the report.
Have you confirmed that the same code works with Spring Security 6.2.2?
Hi @marcusdacoregio, no, it doesn't work in 6.2.2 either.
Comment From: marcusdacoregio
Hi @nnl-1. Do you mind elaborating on why do you need the io.imi.aot_test.auth.CheckRolesLdapAuthenticationProvider#authenticate to be annotated with @Transactional? I'm asking because I don't see it often, users usually prefer annotating the business classes with transactional instead.
The error is thrown by this line on the Spring Authorization Server project, where it tries to autowire dependencies into the AuthenticationProviders.
Comment From: nnl-1
@marcusdacoregio well, I'm saving some info about logged user into DB. I could switch to TransactionTemplate of course but the annotation is more convenient.
Comment From: marcusdacoregio
Thanks, I am looking into this. I suspect that we will have to tweak the AutowireBeanFactoryObjectPostProcessor to use the existing bean if the object is a CGLIB proxy and the application is a native image.
Comment From: marcusdacoregio
Thanks, @nnl-1. This has now been fixed as I described in my previous comment. The snapshots should be published in a few minutes, it would be great if you could test them and report back.