spring-projects / spring-projects/spring-framework

@Lazy not working in Native mode

Open
#30,985 17 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core theme: aot type: bug
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Given the following sample: https://github.com/Eng-Fouad/spring-native-lazy-bug

I got an exception on running the native image:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.2)

2023-08-03T10:42:08.610Z  INFO 1 --- [           main] i.f.l.SpringLazyNativeApplication        : Starting AOT-processed SpringLazyNativeApplication using Java 17.0.7 with PID 1 (/workspace/io.fouad.lazynative.SpringLazyNativeApplication started by cnb in /workspace)
2023-08-03T10:42:08.610Z  INFO 1 --- [           main] i.f.l.SpringLazyNativeApplication        : No active profile set, falling back to 1 default profile: "default"
2023-08-03T10:42:08.658Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-08-03T10:42:08.662Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-08-03T10:42:08.663Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.11]
2023-08-03T10:42:08.675Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-08-03T10:42:08.675Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 64 ms
2023-08-03T10:42:08.690Z  WARN 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleController': Instantiation of supplied bean failed
2023-08-03T10:42:08.690Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-08-03T10:42:08.692Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleController': Instantiation of supplied bean failed
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1220) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at io.fouad.lazynative.SpringLazyNativeApplication.main(SpringLazyNativeApplication.java:12) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
Caused by: org.springframework.aop.framework.AopConfigException: Unexpected AOP exception
        at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:228) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:155) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(ContextAnnotationAutowireCandidateResolver.java:143) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(ContextAnnotationAutowireCandidateResolver.java:84) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(ContextAnnotationAutowireCandidateResolver.java:54) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1334) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) ~[na:na]
        at org.springframework.beans.factory.support.RegisteredBean.resolveAutowiredArgument(RegisteredBean.java:228) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:314) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:260) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:200) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        ... 17 common frames omitted
Caused by: java.lang.ClassCastException: org.springframework.aop.framework.CglibAopProxy$SerializableNoOp cannot be cast to org.springframework.cglib.proxy.Dispatcher
        at io.fouad.lazynative.SampleService$$SpringCGLIB$$0.setCallbacks(<generated>) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
        at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:91) ~[na:na]
        at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:213) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        ... 30 common frames omitted

When removing @Aspect, I got this exception:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.2)

2023-08-02T16:38:05.094Z  INFO 1 --- [           main] s.SpringLazyNativeApplication : Starting AOT-processed SpringLazyNativeApplication using Java 17.0.7 with PID 1 (/workspace/io.fouad.lazynative.SpringLazyNativeApplication started by cnb in /workspace)
2023-08-02T16:38:05.094Z  INFO 1 --- [           main] s.SpringLazyNativeApplication : No active profile set, falling back to 1 default profile: "default"
2023-08-02T16:38:05.108Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-08-02T16:38:05.109Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-08-02T16:38:05.109Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.11]
2023-08-02T16:38:05.118Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-08-02T16:38:05.118Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 24 ms
2023-08-02T16:38:05.124Z  WARN 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleController': Instantiation of supplied bean failed
2023-08-02T16:38:05.124Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-08-02T16:38:05.126Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleController': Instantiation of supplied bean failed
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1220) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[io.fouad.lazynative.SpringLazyNativeApplication:3.1.2]
        at io.fouad.lazynative.SpringLazyNativeApplication.main(SpringLazyNativeApplication.java:10) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class io.fouad.lazynative.SampleService: Common causes of this problem include using a final class or a non-visible class
        at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:222) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:155) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(ContextAnnotationAutowireCandidateResolver.java:143) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(ContextAnnotationAutowireCandidateResolver.java:84) ~[na:na]
        at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver.getLazyResolutionProxyIfNecessary(ContextAnnotationAutowireCandidateResolver.java:54) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1334) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) ~[na:na]
        at org.springframework.beans.factory.support.RegisteredBean.resolveAutowiredArgument(RegisteredBean.java:228) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:314) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:260) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:200) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        ... 17 common frames omitted
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.NoSuchMethodException-->io.fouad.lazynative.SampleService$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;)
        at org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData.<init>(Enhancer.java:501) ~[na:na]
        at org.springframework.cglib.proxy.Enhancer.wrapCachedClass(Enhancer.java:801) ~[na:na]
        at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:108) ~[na:na]
        at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) ~[na:na]
        at java.base@17.0.7/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[io.fouad.lazynative.SpringLazyNativeApplication: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) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        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:213) ~[io.fouad.lazynative.SpringLazyNativeApplication:6.0.11]
        ... 30 common frames omitted
Caused by: java.lang.NoSuchMethodException: io.fouad.lazynative.SampleService$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;)
        at java.base@17.0.7/java.lang.Class.checkMethod(DynamicHub.java:1040) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
        at java.base@17.0.7/java.lang.Class.getDeclaredMethod(DynamicHub.java:1130) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
        at org.springframework.cglib.proxy.Enhancer.getCallbacksSetter(Enhancer.java:901) ~[na:na]
        at org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData.<init>(Enhancer.java:490) ~[na:na]
        ... 42 common frames omitted

Removing @Lazy in both cases, resolves the problem for me and the native image works normally.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked spring-native-lazy-bug sample and reproduce the native-image failure, then trace the stack from ContextAnnotationAutowireCandidateResolver through CglibAopProxy and ObjenesisCglibAopProxy. Done means @Lazy application startup succeeds in native mode for the reported cases, including when the service uses @Aspect.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.