{"record":{"id":"7d97f51ff4d798c9","repo":"spring-projects/spring-framework","slug":"no-suitable-constructor-or-factory-method-found","errorCode":null,"errorMessage":"no suitable constructor or factory method found","messagePattern":"no suitable constructor or factory method found","errorType":"exception","errorClass":"AotBeanProcessingException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java","lineNumber":150,"sourceCode":"\t}\n\n\t/**\n\t * Generate the instance supplier code.\n\t * @param registeredBean the bean to handle\n\t * @param instantiationDescriptor the executable to use to create the bean\n\t * @return the generated code\n\t * @since 6.1.7\n\t */\n\tpublic CodeBlock generateCode(RegisteredBean registeredBean, InstantiationDescriptor instantiationDescriptor) {\n\t\tExecutable constructorOrFactoryMethod = instantiationDescriptor.executable();\n\t\tregisterRuntimeHintsIfNecessary(registeredBean, constructorOrFactoryMethod);\n\t\tif (constructorOrFactoryMethod instanceof Constructor<?> constructor) {\n\t\t\treturn generateCodeForConstructor(registeredBean, constructor);\n\t\t}\n\t\tif (constructorOrFactoryMethod instanceof Method method && !KotlinDetector.isSuspendingFunction(method)) {\n\t\t\treturn generateCodeForFactoryMethod(registeredBean, method, instantiationDescriptor.targetClass());\n\t\t}\n\t\tthrow new AotBeanProcessingException(registeredBean, \"no suitable constructor or factory method found\");\n\t}\n\n\tprivate void registerRuntimeHintsIfNecessary(RegisteredBean registeredBean, Executable constructorOrFactoryMethod) {\n\t\tif (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf) {\n\t\t\tRuntimeHints runtimeHints = this.generationContext.getRuntimeHints();\n\t\t\tProxyRuntimeHintsRegistrar registrar = new ProxyRuntimeHintsRegistrar(dlbf.getAutowireCandidateResolver());\n\t\t\tregistrar.registerRuntimeHints(runtimeHints, constructorOrFactoryMethod);\n\t\t}\n\t}\n\n\tprivate CodeBlock generateCodeForConstructor(RegisteredBean registeredBean, Constructor<?> constructor) {\n\t\tConstructorDescriptor descriptor = new ConstructorDescriptor(\n\t\t\t\tregisteredBean.getBeanName(), constructor, registeredBean.getBeanClass());\n\n\t\tClass<?> publicType = descriptor.publicType();\n\t\tif (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {\n\t\t\treturn generateCodeForInaccessibleConstructor(descriptor,\n\t\t\t\t\thints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java#L132-L168","documentation":"Thrown as an AotBeanProcessingException 'no suitable constructor or factory method found' when InstanceSupplierCodeGenerator.generateCode is given an InstantiationDescriptor whose executable is neither a Constructor nor a non-Kotlin-suspending Method. The code generator only knows how to emit code for those two shapes; anything else (a Kotlin suspending function, or a future Executable subclass) is rejected.","triggerScenarios":"Calling InstanceSupplierCodeGenerator.generateCode(registeredBean, descriptor) where descriptor.executable() is a Kotlin suspending method, or some non-Constructor/non-(plain Method) Executable. Reached during AOT generation of the instance supplier for a bean whose resolved instantiation executable is not supported.","commonSituations":"Bean whose factory method is a Kotlin suspending function (coroutine); custom InstantiationDescriptor built programmatically with an unsupported executable; mismatch between Kotlin coroutines support and Spring version; bean factory method that returns a coroutine Publisher/Flow not handled by the codegen path in this Spring version.","solutions":["If the bean uses Kotlin, ensure kotlin-reflect and a Spring version with coroutine AOT support are present, and avoid marking the bean factory method 'suspend'.","Refactor the factory method to a non-suspending method or a plain constructor so the code generator can emit code for it.","Update Spring Framework to a version whose InstanceSupplierCodeGenerator supports the executable shape you are using.","Register the bean differently (constructor injection, or a non-suspending @Bean method that bridges the coroutine internally).","Exclude the bean from AOT if the coroutine nature is essential and no AOT path exists yet."],"exampleFix":"// before: Kotlin suspending factory method the code generator rejects\n@Bean\nsuspend fun myBean(): MyBean = ... // suspending\n\n// after: non-suspending factory method\n@Bean\nfun myBean(): MyBean = runBlocking { ... }","handlingStrategy":"validation","validationCode":"Executable e = instantiationDescriptor.executable();\nboolean supported = e instanceof Constructor<?> ||\n    (e instanceof Method m && !KotlinDetector.isSuspendingFunction(m));\nif (!supported) {\n    throw new IllegalStateException(\"Cannot AOT-generate supplier for executable: \" + e);\n}","typeGuard":"boolean codegenSupported =\n    (executable instanceof Constructor<?>) ||\n    (executable instanceof Method m && !KotlinDetector.isSuspendingFunction(m));","tryCatchPattern":null,"preventionTips":["Avoid 'suspend' on @Bean factory methods when targeting native image.","Keep kotlin-reflect and a Spring version with coroutine AOT support in sync.","Use plain constructors or non-suspending factory methods for AOT beans.","Test AOT generation in CI for Kotlin beans."],"tags":["spring","aot","kotlin","coroutines","factory-method"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}