spring-projects/spring-framework · error · IllegalArgumentException

Property 'serviceLocatorInterface' is required

Error message

Property 'serviceLocatorInterface' is required

What it means

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.

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 e8729d0438)

Solutions

  1. 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).
  2. If using XML: add <property name="serviceLocatorInterface" value="com.acme.MyServiceFactory"/> inside the <bean> element whose class is ServiceLocatorFactoryBean.
  3. If using Java @Bean: call factoryBean.setServiceLocatorInterface(MyServiceFactory.class) before returning the bean.
  4. 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).
  5. 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.

Example fix

// before (XML)
<bean id="myServiceFactory"
      class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"/>

// after
<bean id="myServiceFactory"
      class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
  <property name="serviceLocatorInterface" value="com.acme.MyServiceFactory"/>
</bean>

// before (Java)
@Bean
public ServiceLocatorFactoryBean myServiceFactory() {
    return new ServiceLocatorFactoryBean();
}

// after
@Bean
public ServiceLocatorFactoryBean myServiceFactory() {
    ServiceLocatorFactoryBean fb = new ServiceLocatorFactoryBean();
    fb.setServiceLocatorInterface(MyServiceFactory.class);
    return fb;
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the FactoryBean configuration before the Spring container starts it.
ServiceLocatorFactoryBean fb = new ServiceLocatorFactoryBean();
fb.setBeanFactory(applicationContext);
// Pre-check the required property the same way afterPropertiesSet() will.
if (fb.getObjectType() == null) {
    throw new IllegalStateException(
        "ServiceLocatorFactoryBean is missing the required 'serviceLocatorInterface' property");
}
fb.afterPropertiesSet();

Type guard

// No runtime type guard; this is a bean-definition validation error. Guard at config time
// by asserting the interface Class is non-null before calling setServiceLocatorInterface.
java.util.Objects.requireNonNull(serviceLocatorInterface,
    "serviceLocatorInterface must not be null");

Try / catch

// The error is fatal and surfaces during context initialization; catch IllegalArgumentException
// around afterPropertiesSet() only to add context, not to recover.
try {
    fb.afterPropertiesSet();
} catch (IllegalArgumentException ex) {
    throw new BeanInitializationException(
        "Misconfigured ServiceLocatorFactoryBean bean '" + beanName + "': " + ex.getMessage(), ex);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/5dfa2a7da35a84be.json. Report an issue: GitHub.