In the spring-native sample class-proxies-aop in the branch sb-3.0.x, the @Aspect works when running in AOT mode, but not in a native-image. There's no exception, the aspect just doesn't get executed.

Comment From: sdeleuze

Likely depends on #28115.

Comment From: snicoll

The proxy is now created properly but the aspect smoke test still fails.

Comment From: sdeleuze

I was able to make it work with:

static class AspectRuntimeHints implements RuntimeHintsRegistrar {
        @Override
        public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
            hints.reflection().registerType(TestAspect.class,
                    builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_METHODS));
            hints.proxies().registerJdkProxy(FactoryBean.class, BeanClassLoaderAware.class, ApplicationListener.class);
            hints.proxies().registerJdkProxy(ApplicationAvailability.class, ApplicationListener.class);
        }
    }

Reflection hint should probably be inferred on Spring Framework side.

The 2 proxies are required by org.springframework.boot.availability.ApplicationAvailabilityBean and org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar and are not created automatically by my #28980 local fix (@jhoeller could you please confirm that's expected?). Related stacktrace is:

at java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:48) ~[aspect:na]
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:398) ~[aspect:na]
    at org.springframework.util.ClassUtils.createCompositeInterface(ClassUtils.java:784) ~[na:na]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getTargetShadowMatch(AspectJExpressionPointcut.java:437) ~[na:na]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:295) ~[na:na]
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:251) ~[na:na]
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:288) ~[na:na]
    at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:320) ~[na:na]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:128) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:97) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:78) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:366) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:318) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:435) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1757) ~[aspect:6.0.0-SNAPSHOT]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[aspect:6.0.0-SNAPSHOT]

If it is confirmed those can't be inferred, I guess those proxies hints should be contributed on Boot side

Comment From: sdeleuze

Looks like the aspect smoke test samples now work, but there are other issues preventing it to work in a reliable fashion for various use case. #29519 is likely one of the blockers.

Comment From: sdeleuze

We should also check if aspect annotations and the methods and classes where they are applied are available via reflection, I suspect #29765 sample is broken by annotation not accessible via reflection on native.

Comment From: sdeleuze

We could potentially reuse Spring AOP infrastructure to identify the reflection entries needed to make aspects working out of the box. We could create a dedicated BeanFactoryInitializationAotProcessor that would use BeanFactoryAspectJAdvisorsBuilder to get the List<Advisor> and process each of them. Maybe we could get the needed information for inference via instanceof PointcutAdvisor and instanceof AbstractAspectJAdvice checks.

Comment From: sdeleuze

Sorry for moving that again, but I won't have the bandwidth to tackle that in Spring 6.0 timeframe, so let's target 6.1.

Comment From: sdeleuze

This fix has been tested successfully with a few samples (including spring-aot-smoke-test/framework/aspect one).

30529 repro is still broken for reasons that remain to be identified, but this will be handle via the dedicated issue.

Feedback welcome.

Comment From: snicoll

I believe this broke the batch AOT sample as follows:

Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
        at org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory.<clinit>(AbstractAspectJAdvisorFactory.java:61)
        at org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder.<init>(BeanFactoryAspectJAdvisorsBuilder.java:60)
        at org.springframework.aop.aspectj.annotation.AspectJBeanFactoryInitializationAotProcessor.processAheadOfTime(AspectJBeanFactoryInitializationAotProcessor.java:44)
        at org.springframework.context.aot.BeanFactoryInitializationAotContributions.getContributions(BeanFactoryInitializationAotContributions.java:67)
        at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:49)
        at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:44)
        at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
        at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
        at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
        at org.springframework.context.aot.ContextAotProcessor.performAotProcessing(ContextAotProcessor.java:106)
        at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:84)
        at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:49)
        at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
        at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:80)
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Pointcut
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 14 more

The batch sample is failing. I don't know if it is special or if something else is involved.

Comment From: snicoll

Fixed by https://github.com/spring-projects/spring-framework/commit/74155e3d88faba9ee6815966b54a0ec34e7adf07