spring-projects/spring-framework · error · IllegalArgumentException
Property 'serviceLocatorInterface' is required
Error message
Property 'serviceLocatorInterface' is required
What it means
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.
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.
Example fix
<!-- before (broken) --> <bean id="f" class="...ServiceLocatorFactoryBean"/> <!-- after --> <bean id="f" class="...ServiceLocatorFactoryBean"> <property name="serviceLocatorInterface" value="com.example.ServiceFactory"/> </bean>
Defensive patterns
Strategy: validation
Validate before calling
if (locatorInterface == null) {
throw new IllegalStateException("serviceLocatorInterface is required");
}
fb.setServiceLocatorInterface(locatorInterface); Type guard
static boolean isLocatorInterface(Class<?> c) {
return c != null && c.isInterface();
} Try / catch
try {
fb.afterPropertiesSet();
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("serviceLocatorInterface")) {
// set the interface from config, then retry
}
throw ex;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- 'propertyPath' is required
- ServiceLocatorFactoryBean needs to run in a BeanFactory…
- 'sourceList' is required
- 'sourceMap' is required
- Specify 'targetObject' or 'targetBeanName' in combination…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/5dfa2a7da35a84be.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java:259
* with service ids as keys as bean names as values
*/
public void setServiceMappings(Properties serviceMappings) {
this.serviceMappings = serviceMappings;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (!(beanFactory instanceof ListableBeanFactory lbf)) {
throw new FatalBeanException(
"ServiceLocatorFactoryBean needs to run in a BeanFactory that is a ListableBeanFactory");
}
this.beanFactory = lbf;
}
@Override
public void afterPropertiesSet() {
if (this.serviceLocatorInterface == null) {
throw new IllegalArgumentException("Property 'serviceLocatorInterface' is required");
}
// Create service locator proxy.
this.proxy = Proxy.newProxyInstance(
this.serviceLocatorInterface.getClassLoader(),
new Class<?>[] {this.serviceLocatorInterface},
new ServiceLocatorInvocationHandler());
}
/**
* Determine the constructor to use for the given service locator exception
* class. Only called in case of a custom service locator exception.
* <p>The default implementation looks for a constructor with one of the
* following parameter types: {@code (String, Throwable)}
* or {@code (Throwable)} or {@code (String)}.
* @param exceptionClass the exception class
* @return the constructor to useView on GitHub (pinned to 69bf83ad71)