{"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":"exception","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/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java#L241-L277","documentation":"Thrown by ServiceLocatorFactoryBean.afterPropertiesSet() during bean initialization when the 'serviceLocatorInterface' property was never set. ServiceLocatorFactoryBean works by generating a dynamic JDK Proxy that implements an interface you supply (a service-locator contract such as MyService getService()); without that interface it has nothing to proxy and no factory methods to delegate, so it refuses to initialize. The check is a hard precondition of the FactoryBean lifecycle: Spring calls afterPropertiesSet() after all setter injections, and at that point the field is still null.","triggerScenarios":"Defining a bean of class org.springframework.beans.factory.config.ServiceLocatorFactoryBean (XML <bean> or @Bean method) and omitting the <property name=\"serviceLocatorInterface\" value=\"...\"/> / .setServiceLocatorInterface(MyFactory.class) call. Also triggered by a typo in the property name (e.g. serviceInterface, locatorInterface), or by passing a null/empty value, or by Java config that constructs the FactoryBean but forgets to invoke setServiceLocatorInterface() before returning it.","commonSituations":"Migrating from ObjectFactoryCreatingFactoryBean and copying only part of the config; renaming the locator interface and forgetting to update the FQN string; XML config where the property element was deleted during a merge; @Configuration @Bean method that calls new ServiceLocatorFactoryBean() and returns it bare; copy-paste from a working bean definition that drops the single required property.","solutions":["Set the serviceLocatorInterface property on the ServiceLocatorFactoryBean bean, pointing at a service-locator interface (e.g. MyServiceFactory) whose methods have signature MyType xxx() or MyType xxx(MyIdType id).","If using XML: add <property name=\"serviceLocatorInterface\" value=\"com.acme.MyServiceFactory\"/> inside the <bean> element whose class is ServiceLocatorFactoryBean.","If using Java @Bean: call factoryBean.setServiceLocatorInterface(MyServiceFactory.class) before returning the bean.","Verify the interface fully-qualified name resolves on the classpath (typo or missing class triggers a different error but is worth ruling out alongside this fix).","Ensure the interface has at least one method returning a non-void type with zero or one argument, otherwise the proxy will build but fail at invocation time."],"exampleFix":"// before (XML)\n<bean id=\"myServiceFactory\"\n      class=\"org.springframework.beans.factory.config.ServiceLocatorFactoryBean\"/>\n\n// after\n<bean id=\"myServiceFactory\"\n      class=\"org.springframework.beans.factory.config.ServiceLocatorFactoryBean\">\n  <property name=\"serviceLocatorInterface\" value=\"com.acme.MyServiceFactory\"/>\n</bean>\n\n// before (Java)\n@Bean\npublic ServiceLocatorFactoryBean myServiceFactory() {\n    return new ServiceLocatorFactoryBean();\n}\n\n// after\n@Bean\npublic ServiceLocatorFactoryBean myServiceFactory() {\n    ServiceLocatorFactoryBean fb = new ServiceLocatorFactoryBean();\n    fb.setServiceLocatorInterface(MyServiceFactory.class);\n    return fb;\n}","handlingStrategy":"validation","validationCode":"// Validate the FactoryBean configuration before the Spring container starts it.\nServiceLocatorFactoryBean fb = new ServiceLocatorFactoryBean();\nfb.setBeanFactory(applicationContext);\n// Pre-check the required property the same way afterPropertiesSet() will.\nif (fb.getObjectType() == null) {\n    throw new IllegalStateException(\n        \"ServiceLocatorFactoryBean is missing the required 'serviceLocatorInterface' property\");\n}\nfb.afterPropertiesSet();","typeGuard":"// No runtime type guard; this is a bean-definition validation error. Guard at config time\n// by asserting the interface Class is non-null before calling setServiceLocatorInterface.\njava.util.Objects.requireNonNull(serviceLocatorInterface,\n    \"serviceLocatorInterface must not be null\");","tryCatchPattern":"// The error is fatal and surfaces during context initialization; catch IllegalArgumentException\n// around afterPropertiesSet() only to add context, not to recover.\ntry {\n    fb.afterPropertiesSet();\n} catch (IllegalArgumentException ex) {\n    throw new BeanInitializationException(\n        \"Misconfigured ServiceLocatorFactoryBean bean '\" + beanName + \"': \" + ex.getMessage(), ex);\n}","preventionTips":["Always pair a ServiceLocatorFactoryBean bean definition with its serviceLocatorInterface property in the same edit; treat them as a single unit.","Centralize the @Bean definition in one @Configuration method rather than scattering XML/Java config so the setServiceLocatorInterface call cannot be silently dropped.","Add a context-startup smoke test (e.g. @SpringBootTest or a stand-alone ClassPathXmlApplicationContext load) to CI so a missing required property fails the build instead of staging.","When renaming or relocating the locator interface, grep for both the FQN string and setServiceLocatorInterface to update every reference."],"tags":["spring","spring-beans","factorybean","configuration","bean-lifecycle","java"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}