Hi, I've been trying to use native image support offered in spring boot 3.x.

Problem

When running a graalvm generated native image/executable, ClassPathScanningCandidateComponentProvider doesn't seem to be able to find interfaces/classes with annotation.

Runnable example

More information/instructions and a runnable example are provided at https://github.com/GoncaloPT/native-annotation-find.

Versions used

spring-boot: 3.2.0-SNAPSHOT jdk: Liberica-NIK-23.0.0-1 (build 20.0.1+10)

Comment From: GoncaloPT

Could it be somehow related with https://github.com/spring-projects/spring-framework/issues/29163

Comment From: GoncaloPT

I was able to fix it by adding a new entry in resource config for the classes i want to inspect with reflection.

Maybe therefore this issue can be closed, or maybe PathMatchingResourcePatternResolver could be improved to highlight a little bit more that resources are being skipped.

In the reproducer attached, the logs that caught my attention - after a few hours - were: 2023-09-15T00:20:52.601+01:00 INFO 14904 --- [ main] .i.s.PathMatchingResourcePatternResolver : Skipping search for files matching pattern [**/*.class]: directory [/pt/goncalo/reproducer/nativeannotationfind/other] does not exist.

After seeing it I realized that perhaps I should add files instead of annotation configurations... which seems very odd to be honest.

Comment From: bclozel

You are not supposed to read class files as resources and inspect their bytecode at runtime in a native image. This defeats the purpose of native and goes against the closed world assumptions required for an efficient native image.

You should instead use the AOT infrastructure to perform those operations during the AOT phase.

Comment From: GoncaloPT

Hello @bclozel. I see, it is a different kind of mindset. What would be the best way of doing it? Give up on reflection and use other tools ( code generation?! )?

As a user is very confusing to understand what we must or not register since spring already does a lot of magic. I don't even know if a should open issues or just give up on native. For instance, projections (JPA) with SPEL ( target proxy ) are not working on my side; are they supposed to work?

Comment From: bclozel

What would be the best way of doing it? Give up on reflection and use other tools ( code generation?! )?

That's the goal of the entire AOT engine. All Spring projects (Framework, Data, GraphQL, etc) looking at annotations at runtime and processing them for registrations or proxy generation are using the AOT engine. Sometimes it can be as easy as registering a few GraalVM reachability hints (if you're not scanning the classpath but rather getting beans from the application context).

This solution only applies for Spring applications, as other libraries and frameworks might have chosen a different approach. I think that Spring Data projections should work already; maybe you're hitting a specific limitation? In any case, you should open an issue against Spring Data JPA in this case because the supporting AOT code lives there.