{"record":{"id":"9a5f54891b6ca094","repo":"spring-projects/spring-framework","slug":"cannot-invoke-instance-method-without-factorybeann","errorCode":null,"errorMessage":"Cannot invoke instance method without factoryBeanName: ","messagePattern":"Cannot invoke instance method without factoryBeanName: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java","lineNumber":361,"sourceCode":"\t}\n\n\tprivate Object instantiate(RegisteredBean registeredBean, Executable executable, @Nullable Object[] args) {\n\t\tif (executable instanceof Constructor<?> constructor) {\n\t\t\tif (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf &&\n\t\t\t\t\tregisteredBean.getMergedBeanDefinition().hasMethodOverrides()) {\n\t\t\t\treturn dlbf.getInstantiationStrategy().instantiate(registeredBean.getMergedBeanDefinition(),\n\t\t\t\t\t\tregisteredBean.getBeanName(), registeredBean.getBeanFactory());\n\t\t\t}\n\t\t\treturn BeanUtils.instantiateClass(constructor, args);\n\t\t}\n\t\tif (executable instanceof Method method) {\n\t\t\tObject target = null;\n\t\t\tString factoryBeanName = registeredBean.getMergedBeanDefinition().getFactoryBeanName();\n\t\t\tif (factoryBeanName != null) {\n\t\t\t\ttarget = registeredBean.getBeanFactory().getBean(factoryBeanName, method.getDeclaringClass());\n\t\t\t}\n\t\t\telse if (!Modifier.isStatic(method.getModifiers())) {\n\t\t\t\tthrow new IllegalStateException(\"Cannot invoke instance method without factoryBeanName: \" + method);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tReflectionUtils.makeAccessible(method);\n\t\t\t\treturn method.invoke(target, args);\n\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tthrow new BeanInstantiationException(method, ex.getMessage(), ex);\n\t\t\t}\n\t\t}\n\t\tthrow new IllegalStateException(\"Unsupported executable \" + executable.getClass().getName());\n\t}\n\n\n\tprivate static String toCommaSeparatedNames(Class<?>... parameterTypes) {\n\t\treturn Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(\", \"));\n\t}\n\n","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java#L343-L379","documentation":"Thrown as an IllegalStateException when the BeanInstanceSupplier is told to invoke a factory method that is non-static, but the bean definition has no factoryBeanName set. Without a factoryBeanName the supplier has no bean to obtain as the invocation target, so it refuses rather than NPE on method.invoke(null, args).","triggerScenarios":"The instantiation descriptor select a java.lang.reflect.Method that is an instance method (not static), but RootBeanDefinition.getFactoryBeanName() returns null. Triggered in BeanInstanceSupplier.instantiate when building the bean instance via reflection at runtime.","commonSituations":"Programmatically building a RootBeanDefinition with setFactoryMethodName(name) on an instance method but forgetting setFactoryBeanName(...); a @Bean method that was inadvertently changed from static to instance without updating factory metadata; custom BeanDefinitionRegistryPostProcessor that misconfigures factory method metadata; stale AOT metadata generated against a static factory that later became an instance method.","solutions":["Set the factoryBeanName on the bean definition: definition.setFactoryBeanName(\"myFactory\"); so the supplier can resolve the target bean.","If the factory method should not need an instance, mark it static so the supplier can invoke it without a target.","Regenerate AOT artifacts after changing a @Bean method between static and instance forms so the metadata matches the code.","Validate the bean definition programmatically (factoryBeanName != null XOR Modifier.isStatic(factoryMethod)) before publishing it."],"exampleFix":"// before: instance factory method without a factoryBeanName\nRootBeanDefinition bd = new RootBeanDefinition(MyBean.class);\nbd.setFactoryMethodName(\"create\"); // create() is non-static\n\n// after: provide the factory bean name\nbd.setFactoryBeanName(\"myFactory\");\nbd.setFactoryMethodName(\"create\");","handlingStrategy":"validation","validationCode":"// Validate factory-method metadata before publishing a bean definition\nRootBeanDefinition bd = (RootBeanDefinition) beanDefinition;\nMethod fm = /* resolved factory method */;\nif (!Modifier.isStatic(fm.getModifiers()) && bd.getFactoryBeanName() == null) {\n    throw new IllegalStateException(\"Instance factory method requires factoryBeanName: \" + fm);\n}","typeGuard":"// True if the bean definition can be invoked without an instance target\nboolean canInvoke = Modifier.isStatic(method.getModifiers()) || factoryBeanName != null;","tryCatchPattern":null,"preventionTips":["Always set factoryBeanName for instance factory methods in programmatic definitions.","Prefer @Bean methods on @Configuration classes over hand-built RootBeanDefinition.","Regenerate AOT artifacts after changing a factory method's static/instance form.","Add a BeanDefinition validation post-processor that checks this invariant."],"tags":["spring","aot","factory-method","bean-definition","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}