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

  1. Add <property name="serviceLocatorInterface" value="com.example.ServiceFactory"/> pointing at an interface with methods like 'MyType getService()' or 'MyType getService(String id)'.
  2. In code, call setServiceLocatorInterface(ServiceFactory.class) before initialization.
  3. 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

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


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 use

View on GitHub (pinned to 69bf83ad71)