spring-framework
spring-framework copied to clipboard
@Lazy not working in Native mode
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 [email protected]/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 [email protected]/java.lang.Class.checkMethod(DynamicHub.java:1040) ~[io.fouad.lazynative.SpringLazyNativeApplication:na]
at [email protected]/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.
I tried registering SampleService
as reflection hint, but it didn't fix the problem:
MyRuntimeHints:
package io.fouad.lazynative;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
public class MyRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(SampleService.class);
}
}
SpringLazyNativeApplication:
package io.fouad.lazynative;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportRuntimeHints;
@SpringBootApplication
@ImportRuntimeHints(MyRuntimeHints.class)
public class SpringLazyNativeApplication {
public static void main(String[] args) {
System.out.println("Hello World");
org.springframework.boot.SpringApplication.run(SpringLazyNativeApplication.class, args);
}
}
@Eng-Fouad thanks for the report and the sample but please move all that text into an actual sample that we can run. The only thing we could to help is to do that anyway and there's a chance in doing so that we miss one piece. An url to a GitHub repo is ideal or, alternatively, a ZIP attached to this issue.
@Eng-Fouad thanks for the report and the sample but please move all that text into an actual sample that we can run. The only thing we could to help is to do that anyway and there's a chance in doing so that we miss one piece. An url to a GitHub repo is ideal or, alternatively, a ZIP attached to this issue.
Here it is: https://github.com/Eng-Fouad/spring-native-lazy-bug
As a workaround for the second exception:
Caused by: java.lang.NoSuchMethodException: io.fouad.lazynative.SampleService$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;)
package io.fouad.springnativelazybug;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.support.ClassHintUtils;
public class MyRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
registerClass(hints, SampleService.class);
}
private static <T> void registerClass(RuntimeHints hints, Class<T> clazz) {
for (int i = 0;; i++) {
Class<?> proxyClass;
try {
proxyClass = Class.forName("%s$$SpringCGLIB$$%d".formatted(clazz.getName(), i));
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
ClassHintUtils.registerProxyIfNecessary(proxyClass, hints);
}
}
}
Similar #29584 #29309
I just checked. It's working fine. Their is no exception while running the application. Is it fixed?
I just checked. It's working fine. Their is no exception while running the application. Is it fixed?
Did you run the native image?
Assign me. I am working on that. Will give it you in an hour. Because I have checked it and solve it.
Assign me. I am working on that. Will give it you in an hour. Because I have checked it and solve it.
How did you solve this exception?
Caused by: java.lang.ClassCastException: org.springframework.aop.framework.CglibAopProxy$SerializableNoOp cannot be cast to org.springframework.cglib.proxy.Dispatcher