{"record":{"id":"5dfa2a7da35a84be","repo":"spring-projects/spring-framework","slug":"property-servicelocatorinterface-is-required","errorCode":null,"errorMessage":"Property 'serviceLocatorInterface' is required","messagePattern":"Property 'serviceLocatorInterface' is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java","lineNumber":259,"sourceCode":"\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\n\n\t/**\n\t * Determine the constructor to use for the given service locator exception\n\t * class. Only called in case of a custom service locator exception.\n\t * <p>The default implementation looks for a constructor with one of the\n\t * following parameter types: {@code (String, Throwable)}\n\t * or {@code (Throwable)} or {@code (String)}.\n\t * @param exceptionClass the exception class\n\t * @return the constructor to use","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java#L241-L277","documentation":"Thrown by ServiceLocatorFactoryBean.afterPropertiesSet() when serviceLocatorInterface was never set. This FactoryBean builds a dynamic proxy implementing the given locator interface; without an interface there is nothing to proxy and no factory methods to delegate. Spring fails fast at initialization rather than returning a useless null proxy.","triggerScenarios":"XML <bean class=\"...ServiceLocatorFactoryBean\"> with no <property name=\"serviceLocatorInterface\">. Programmatic use without calling setServiceLocatorInterface(...). A placeholder for the interface class name that resolves to null/empty.","commonSituations":"Forgetting the interface property when copying a config template. Placeholder misconfiguration. Refactoring that removed the property. Using the bean as a generic factory without specifying which locator interface to implement.","solutions":["Add <property name=\"serviceLocatorInterface\" value=\"com.example.ServiceFactory\"/> pointing at an interface with methods like 'MyType getService()' or 'MyType getService(String id)'.","In code, call setServiceLocatorInterface(ServiceFactory.class) before initialization.","Verify the interface is an interface (not a class) and is on the classpath, and that any placeholder resolves to its FQN."],"exampleFix":"<!-- before (broken) -->\n<bean id=\"f\" class=\"...ServiceLocatorFactoryBean\"/>\n<!-- after -->\n<bean id=\"f\" class=\"...ServiceLocatorFactoryBean\">\n  <property name=\"serviceLocatorInterface\" value=\"com.example.ServiceFactory\"/>\n</bean>","handlingStrategy":"validation","validationCode":"if (locatorInterface == null) {\n    throw new IllegalStateException(\"serviceLocatorInterface is required\");\n}\nfb.setServiceLocatorInterface(locatorInterface);","typeGuard":"static boolean isLocatorInterface(Class<?> c) {\n    return c != null && c.isInterface();\n}","tryCatchPattern":"try {\n    fb.afterPropertiesSet();\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"serviceLocatorInterface\")) {\n        // set the interface from config, then retry\n    }\n    throw ex;\n}","preventionTips":["Always set serviceLocatorInterface before afterPropertiesSet().","In XML, make <property name=\"serviceLocatorInterface\"/> mandatory via a custom BFPP or review.","Use a context-load test to catch missing required properties at build time."],"tags":["spring","factory-bean","service-locator","configuration","missing-property"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}