spring-projects/spring-framework · error · IllegalArgumentException
Service locator exception [${exceptionClass.getName()}] neit
Error message
Service locator exception [${exceptionClass.getName()}] neither has a (String, Throwable) constructor nor a (String) constructor What it means
Thrown by ServiceLocatorFactoryBean.determineServiceLocatorExceptionConstructor() when the custom exception class set via setServiceLocatorExceptionClass does not expose any of the supported constructors: (String, Throwable), (Throwable), or (String). ServiceLocatorFactoryBean needs to wrap lookup failures (NoSuchBeanDefinitionException etc.) into the user's exception type, and it can only do so reflectively if such a constructor exists. The error message lists the exception class name that failed the check.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java:294
* @param exceptionClass the exception class
* @return the constructor to use
* @see #setServiceLocatorExceptionClass
*/
@SuppressWarnings("unchecked")
protected Constructor<Exception> determineServiceLocatorExceptionConstructor(Class<? extends Exception> exceptionClass) {
try {
return (Constructor<Exception>) exceptionClass.getConstructor(String.class, Throwable.class);
}
catch (NoSuchMethodException ex) {
try {
return (Constructor<Exception>) exceptionClass.getConstructor(Throwable.class);
}
catch (NoSuchMethodException ex2) {
try {
return (Constructor<Exception>) exceptionClass.getConstructor(String.class);
}
catch (NoSuchMethodException ex3) {
throw new IllegalArgumentException(
"Service locator exception [" + exceptionClass.getName() +
"] neither has a (String, Throwable) constructor nor a (String) constructor");
}
}
}
}
/**
* Create a service locator exception for the given cause.
* Only called in case of a custom service locator exception.
* <p>The default implementation can handle all variations of
* message and exception arguments.
* @param exceptionConstructor the constructor to use
* @param cause the cause of the service lookup failure
* @return the service locator exception to throw
* @see #setServiceLocatorExceptionClass
*/
protected Exception createServiceLocatorException(Constructor<Exception> exceptionConstructor, BeansException cause) {View on GitHub (pinned to 69bf83ad71)
Solutions
- Add a public constructor to your exception class with one of: (String, Throwable), (Throwable), or (String). The (String, Throwable) form is preferred so both message and cause propagate.
- If you cannot change the exception class, wrap it in a custom subclass that adds such a constructor, or stop using setServiceLocatorExceptionClass and let Spring throw its own BeansException subclasses.
- Ensure the constructor is public so reflection (Class.getConstructor) can find it.
Example fix
// before (broken)
public class MyException extends RuntimeException {
public MyException(int code) { ... }
}
fb.setServiceLocatorExceptionClass(MyException.class); // throws
// after
public class MyException extends RuntimeException {
public MyException(String msg, Throwable cause) { super(msg, cause); }
public MyException(String msg) { super(msg); }
} Defensive patterns
Strategy: type-guard
Validate before calling
Class<? extends Exception> c = MyException.class;
boolean hasCtor =
hasPublicCtor(c, String.class, Throwable.class) ||
hasPublicCtor(c, Throwable.class) ||
hasPublicCtor(c, String.class);
if (!hasCtor) {
throw new IllegalStateException(c.getName() + " needs a (String,Throwable)/(Throwable)/(String) constructor");
}
fb.setServiceLocatorExceptionClass(c); Type guard
static boolean hasSupportedLocatorExceptionCtor(Class<? extends Exception> c) {
try { c.getConstructor(String.class, Throwable.class); return true; }
catch (NoSuchMethodException ignore) {}
try { c.getConstructor(Throwable.class); return true; }
catch (NoSuchMethodException ignore) {}
try { c.getConstructor(String.class); return true; }
catch (NoSuchMethodException ignore) {}
return false;
} Try / catch
try {
fb.setServiceLocatorExceptionClass(MyException.class);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("neither has a")) {
// add a (String, Throwable) constructor to MyException, then retry
}
throw ex;
} Prevention
- Give every custom service-locator exception at least a public (String, Throwable) constructor.
- Write a unit test asserting the exception class has a supported constructor.
- If you cannot modify the class, do not set serviceLocatorExceptionClass and accept Spring's default BeansException.
When it happens
Trigger: Calling setServiceLocatorExceptionClass(MyException.class) where MyException has only a no-arg or (int) constructor. Providing an exception class with private/package-private constructors that reflection cannot reach. Passing a checked exception whose constructors don't match the supported signatures.
Common situations: Custom business exception without the conventional message/cause constructors. Refactoring the exception class and removing the (String, Throwable) constructor. Using a library exception class whose API differs.
Related errors
- targetField is required
- ServiceLocatorFactoryBean needs to run in a BeanFactory that
- Property 'serviceLocatorInterface' is required
- Failed to invoke init method
- Failed to instantiate method
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/bc76ade6ff3baefa.
Report an issue: GitHub.