Skip to content
New issue

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

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

Already on GitHub? # to your account

@Resource dependency injection fails with AOT/native #29614

Closed
javamichi18 opened this issue Nov 30, 2022 · 8 comments
Closed

@Resource dependency injection fails with AOT/native #29614

javamichi18 opened this issue Nov 30, 2022 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Milestone

Comments

@javamichi18
Copy link

Affects: Spring 6.0.2 / SpringBoot 3.0.0 / GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)


Injection of spring beans fails when using @Resource and native image.
When using @Autowired the dependency injections works as expected.

example project:
https://github.com/javamichi18/graalDependencyTest

e.g.

@Controller
public class API {

    @jakarta.annotation.Resource //--> NPE
    //    @Autowired // --> works
    private TestService service;
mvn spring-boot:build-image -Pnative2
...
[INFO] Successfully built image 'docker.io/library/gdt:0.0.1-SNAPSHOT'
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:25 min
[INFO] Finished at: 2022-11-30T14:30:50+01:00

Run app:
graalDependencyTest % ./target/gdt

Invocation of REST endpoint ...

curl http://localhost:8080/foo
{"timestamp":"2022-11-30T13:34:36.062+00:00","status":500,"error":"Internal Server Error","path":"/foo"}%    

... triggers NullPointerException when using @Resource, but not when using @Autowired.

2022-11-30T14:32:52.710+01:00 ERROR 28966 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
	at com.example.graaldependencytest.API.getFoo(API.java:32) ~[gdt:na]
	at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[gdt:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[gdt:6.0.2]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[gdt:6.0.2]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[gdt:6.0.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[gdt:6.0.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[gdt:6.0.2]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[gdt:6.0.2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[gdt:6.0.2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) ~[gdt:6.0.2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1003) ~[gdt:6.0.2]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:895) ~[gdt:6.0.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:705) ~[gdt:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:880) ~[gdt:6.0.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[gdt:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[na:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[gdt:10.1.1]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[gdt:6.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[gdt:6.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[gdt:6.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[gdt:6.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[gdt:6.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[gdt:6.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[na:na]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[na:na]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[gdt:10.1.1]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[na:na]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[gdt:10.1.1]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[na:na]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[na:na]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[na:na]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[gdt:10.1.1]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[na:na]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[na:na]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[gdt:10.1.1]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[na:na]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[na:na]
	at java.base@17.0.5/java.lang.Thread.run(Thread.java:833) ~[gdt:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:775) ~[gdt:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:203) ~[na:na]

environment:

java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)

Apple Silicon M1 max

I am using the maven build profile native2, because using
mvn spring-boot:build-image -Pnative
leads to a stuck build / running endlessness (> 45 minutes).

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 30, 2022
@javamichi18 javamichi18 changed the title @jakarta.annoation.Resource dependency injection fails when using spring native / GraalVM 22.3 @jakarta.annotaion.Resource dependency injection fails when using spring native / GraalVM 22.3 Nov 30, 2022
@javamichi18 javamichi18 changed the title @jakarta.annotaion.Resource dependency injection fails when using spring native / GraalVM 22.3 @jakarta.annotation.Resource dependency injection fails when using spring native / GraalVM 22.3 Nov 30, 2022
@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing labels Nov 30, 2022
@sbrannen sbrannen added this to the Triage Queue milestone Nov 30, 2022
@hantsy

This comment was marked as off-topic.

@sdeleuze sdeleuze changed the title @jakarta.annotation.Resource dependency injection fails when using spring native / GraalVM 22.3 @Resource dependency injection fails with AOT/native Jan 17, 2023
@sdeleuze sdeleuze self-assigned this Jan 17, 2023
@sdeleuze sdeleuze modified the milestones: Triage Queue, 6.0.5 Jan 17, 2023
@sdeleuze sdeleuze removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 17, 2023
@sdeleuze
Copy link
Contributor

Confirmed, the required reflection hints are missing when using @Resource.

@sdeleuze
Copy link
Contributor

CommonAnnotationBeanPostProcessor should probably be made AOT aware like AutowiredAnnotationBeanPostProcessor is.

@sdeleuze sdeleuze modified the milestones: 6.0.5, 6.0.x Jan 30, 2023
@sdeleuze
Copy link
Contributor

This is doable but more involved than expected, so I prefer to focus on the other issues for 6.0.5.

@sdeleuze
Copy link
Contributor

sdeleuze commented Jul 4, 2023

As we try to empty 6.0.x bucket, and given the various milestone date and summer PTO season, I am moving it back to 6.1.x. Does not prevent to fix it in an upcoming 6.0 specific release, but let's decide when we have more visibility.

@sbrannen
Copy link
Member

CommonAnnotationBeanPostProcessor should probably be made AOT aware like AutowiredAnnotationBeanPostProcessor is.

That should cover support for the application.

However, I think we will need something like AutowiredAnnotationBeanPostProcessor's processInjection(Object) in CommonAnnotationBeanPostProcessor in order to support the use of @Resource in test classes in AOT mode (see also DependencyInjectionTestExecutionListener.injectDependenciesInAotMode(...)).

@jhoeller, thoughts?

@sbrannen sbrannen changed the title @Resource dependency injection fails with AOT/native @Resource and @EJB dependency injection fails with AOT/native Oct 16, 2023
@sbrannen
Copy link
Member

While running tests such as RollbackForRequiresNewEjbTxDaoTestNGTests in the spring-test module in AOT mode, I noticed that we also do not support dependency injection via @EJB (jakarta.ejb.EJB).

I've updated the title of this issue to reflect that.

@snicoll snicoll changed the title @Resource and @EJB dependency injection fails with AOT/native @Resource dependency injection fails with AOT/native Oct 16, 2023
@snicoll
Copy link
Member

snicoll commented Oct 16, 2023

Let's keep the scope of the issue as it is now please. While technically those two are related, I don't see a reason to spend efforts to suport @EJB for AOT at this time.

snicoll added a commit to snicoll/spring-framework that referenced this issue Oct 17, 2023
This commit adds ahead of time support for @resource on fields and
methods. Lookup elements are discovered and code is generated to replace
that introspection at runtime.

Closes spring-projectsgh-29614
@snicoll snicoll self-assigned this Oct 17, 2023
@snicoll snicoll modified the milestones: 6.1.x, 6.1.2 Dec 11, 2023
jhoeller added a commit that referenced this issue Dec 12, 2023
Includes refactored @resource resolver for AOT with lazy resolution support.

Closes gh-31447
See gh-29614
# for free to join this conversation on GitHub. Already have an account? # 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: bug A general bug
Projects
None yet
Development

No branches or pull requests

6 participants