{"record":{"id":"fc06fd9cbe67522c","repo":"spring-projects/spring-framework","slug":"servicelocatorfactorybean-needs-to-run-in-a-beanfa","errorCode":null,"errorMessage":"ServiceLocatorFactoryBean needs to run in a BeanFactory that is a ListableBeanFactory","messagePattern":"ServiceLocatorFactoryBean needs to run in a BeanFactory that is a ListableBeanFactory","errorType":"exception","errorClass":"FatalBeanException","httpStatus":null,"severity":"critical","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java","lineNumber":250,"sourceCode":"\n\t/**\n\t * Set mappings between service ids (passed into the service locator)\n\t * and bean names (in the bean factory). Service ids that are not defined\n\t * here will be treated as bean names as-is.\n\t * <p>The empty string as service id key defines the mapping for {@code null} and\n\t * empty string, and for factory methods without parameter. If not defined,\n\t * a single matching bean will be retrieved from the bean factory.\n\t * @param serviceMappings mappings between service ids and bean names,\n\t * with service ids as keys as bean names as values\n\t */\n\tpublic void setServiceMappings(Properties serviceMappings) {\n\t\tthis.serviceMappings = serviceMappings;\n\t}\n\n\t@Override\n\tpublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {\n\t\tif (!(beanFactory instanceof ListableBeanFactory lbf)) {\n\t\t\tthrow new FatalBeanException(\n\t\t\t\t\t\"ServiceLocatorFactoryBean needs to run in a BeanFactory that is a ListableBeanFactory\");\n\t\t}\n\t\tthis.beanFactory = lbf;\n\t}\n\n\t@Override\n\tpublic void afterPropertiesSet() {\n\t\tif (this.serviceLocatorInterface == null) {\n\t\t\tthrow new IllegalArgumentException(\"Property 'serviceLocatorInterface' is required\");\n\t\t}\n\n\t\t// Create service locator proxy.\n\t\tthis.proxy = Proxy.newProxyInstance(\n\t\t\t\tthis.serviceLocatorInterface.getClassLoader(),\n\t\t\t\tnew Class<?>[] {this.serviceLocatorInterface},\n\t\t\t\tnew ServiceLocatorInvocationHandler());\n\t}\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java#L232-L268","documentation":"Thrown by ServiceLocatorFactoryBean.setBeanFactory() as a FatalBeanException when the enclosing BeanFactory does not implement ListableBeanFactory. ServiceLocatorFactoryBean resolves beans by type (getBean(Class)) when no id is passed, which requires the factory to support listing/iteration over bean definitions - a capability only ListableBeanFactory provides. A plain BeanFactory (e.g. a minimal programmatic DefaultListableBeanFactory subset) cannot satisfy this.","triggerScenarios":"Registering a ServiceLocatorFactoryBean in a context whose BeanFactory is not ListableBeanFactory (rare; most application contexts - ClassPathXmlApplicationContext, AnnotationConfigApplicationContext - use DefaultListableBeanFactory which IS Listable). Constructing an ad-hoc BeanFactory implementation. Certain test harnesses or embedded Spring usage with a stripped factory.","commonSituations":"Programmatically creating a custom BeanFactory and adding a ServiceLocatorFactoryBean. Using a SimpleJndiBeanFactory or similar non-listable factory. Edge cases in framework testing utilities.","solutions":["Run the bean inside a standard ApplicationContext (ClassPathXmlApplicationContext, GenericApplicationContext, AnnotationConfigApplicationContext) - their factories are ListableBeanFactory implementations.","If constructing the factory manually, use DefaultListableBeanFactory instead of a non-listable implementation.","Ensure no custom BeanFactory wrapper hides the ListableBeanFactory interface from the instanceof check."],"exampleFix":"// before (broken): custom non-listable factory\nBeanFactory bf = new MyCustomBeanFactory();\nnew ServiceLocatorFactoryBean().setBeanFactory(bf); // throws\n// after\nDefaultListableBeanFactory bf = new DefaultListableBeanFactory();\nnew ServiceLocatorFactoryBean().setBeanFactory(bf);","handlingStrategy":"type-guard","validationCode":"if (!(beanFactory instanceof ListableBeanFactory)) {\n    throw new IllegalStateException(\n        \"Use a DefaultListableBeanFactory-backed context for ServiceLocatorFactoryBean\");\n}\nfb.setBeanFactory(beanFactory);","typeGuard":"static boolean isListable(BeanFactory bf) {\n    return bf instanceof ListableBeanFactory;\n}","tryCatchPattern":"try {\n    fb.setBeanFactory(beanFactory);\n} catch (FatalBeanException ex) {\n    if (ex.getMessage().contains(\"ListableBeanFactory\")) {\n        // wrap beanFactory in a DefaultListableBeanFactory-backed GenericApplicationContext\n    }\n    throw ex;\n}","preventionTips":["Always run ServiceLocatorFactoryBean inside a standard ApplicationContext.","When building factories manually, default to DefaultListableBeanFactory.","Avoid custom BeanFactory wrappers that hide the ListableBeanFactory interface."],"tags":["spring","factory-bean","service-locator","bean-factory","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}