{"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/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java#L132-L168","documentation":"InstanceSupplierCodeGenerator.generateCode only knows how to emit creation code for a Constructor or a (non-Kotlin-suspending) Method. If the resolved InstantiationDescriptor's executable is neither - for example a Kotlin suspending function used as a factory method, or an exotic executable - it throws AotBeanProcessingException stating no suitable constructor/factory method was found.","triggerScenarios":"A bean's resolved instantiation executable is a Kotlin suspending factory method, or otherwise not a plain Constructor/Method during AOT instance-supplier code generation.","commonSituations":"Kotlin beans instantiated via a suspending companion/object function as a factory method in a native build; beans whose instantiation descriptor could not be resolved to a standard executable.","solutions":["Avoid using a Kotlin suspending function as a bean factory method; use a regular (non-suspending) function or constructor.","Provide an explicit non-suspending factory method or constructor for the bean.","If the executable type is unexpected, ensure the InstantiationDescriptor resolves to a Constructor or Method."],"exampleFix":"// before (Kotlin)\n@Bean fun makeBean() = someSuspendingCall() // suspending\n// after\n@Bean fun makeBean() = blockingCreate() // non-suspending","handlingStrategy":"validation","validationCode":"Executable e = instantiationDescriptor.executable();\nboolean suspending = KotlinDetector.isSuspendingFunction(e);\nif (!(e instanceof Constructor) && (!(e instanceof Method) || suspending)) {\n  throw new IllegalStateException(\"No AOT-supported executable: \" + e);\n}","typeGuard":"boolean isAotSupportedExecutable(Executable e) {\n  return e instanceof Constructor || (e instanceof Method m && !KotlinDetector.isSuspendingFunction(m));\n}","tryCatchPattern":null,"preventionTips":["Do not use Kotlin suspending functions as bean factory methods.","Prefer constructors or regular factory methods for native targets.","Validate bean executables during the AOT dry-run."],"tags":["spring","aot","native","kotlin","factory-method"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}