{"id":"1c408ff1af426d30","repo":"spring-projects/spring-framework","slug":"service-locator-exception-neither-has-a-stri","errorCode":null,"errorMessage":"Service locator exception [{}] neither has a (String, Throwable) constructor nor a (String) constructor","messagePattern":"Service locator exception \\[(.+?)\\] neither has a \\(String, Throwable\\) constructor nor a \\(String\\) constructor","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java","lineNumber":294,"sourceCode":"\t * @param exceptionClass the exception class\n\t * @return the constructor to use\n\t * @see #setServiceLocatorExceptionClass\n\t */\n\t@SuppressWarnings(\"unchecked\")\n\tprotected Constructor<Exception> determineServiceLocatorExceptionConstructor(Class<? extends Exception> exceptionClass) {\n\t\ttry {\n\t\t\treturn (Constructor<Exception>) exceptionClass.getConstructor(String.class, Throwable.class);\n\t\t}\n\t\tcatch (NoSuchMethodException ex) {\n\t\t\ttry {\n\t\t\t\treturn (Constructor<Exception>) exceptionClass.getConstructor(Throwable.class);\n\t\t\t}\n\t\t\tcatch (NoSuchMethodException ex2) {\n\t\t\t\ttry {\n\t\t\t\t\treturn (Constructor<Exception>) exceptionClass.getConstructor(String.class);\n\t\t\t\t}\n\t\t\t\tcatch (NoSuchMethodException ex3) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Service locator exception [\" + exceptionClass.getName() +\n\t\t\t\t\t\t\t\"] neither has a (String, Throwable) constructor nor a (String) constructor\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Create a service locator exception for the given cause.\n\t * Only called in case of a custom service locator exception.\n\t * <p>The default implementation can handle all variations of\n\t * message and exception arguments.\n\t * @param exceptionConstructor the constructor to use\n\t * @param cause the cause of the service lookup failure\n\t * @return the service locator exception to throw\n\t * @see #setServiceLocatorExceptionClass\n\t */\n\tprotected Exception createServiceLocatorException(Constructor<Exception> exceptionConstructor, BeansException cause) {","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.java#L276-L312","documentation":"Thrown by ServiceLocatorFactoryBean.determineServiceLocatorExceptionConstructor() when the class passed to setServiceLocatorExceptionClass() lacks all three required constructors. ServiceLocatorFactoryBean lets you translate internal Spring BeansException failures into a custom application exception; to do that it must be able to construct your exception from either a (String, Throwable) pair, a single (Throwable), or a single (String). If none of those public constructors exists, it cannot wrap the lookup cause and rejects the exception class at configuration time (the setter is called during bean initialization, so the error surfaces as the context fails to start).","triggerScenarios":"Calling setServiceLocatorExceptionClass(MyAppException.class) (XML <property name=\"serviceLocatorExceptionClass\" value=\"...\"/>) where MyAppException only exposes constructors like (int code), (String message, int code), or only a no-arg/default constructor. Also triggered when the exception class is an enum-implementing pseudo-exception, a checked exception with private/package-private constructors, or when the intended (String, Throwable) constructor was renamed/removed during a refactor of the application exception hierarchy.","commonSituations":"Adopting ServiceLocatorFactoryBean and pointing serviceLocatorExceptionClass at a pre-existing domain exception that was designed for business errors (message+code) rather than wrapping; an upgrade that switches the custom exception from a single-String ctor to a (String, ErrorCode) ctor; team shares a common exception that no longer has a Throwable constructor; refactoring error hierarchies without realizing Spring needs one of the three shapes.","solutions":["Add a public constructor to your custom exception class with one of these signatures: (String, Throwable), (Throwable), or (String). The (String, Throwable) form is preferred so both the message and the original cause are preserved.","If you cannot modify the exception class, switch to a different exception class that already has one of the required constructors, or omit setServiceLocatorExceptionClass entirely and let Spring throw its unchecked NoSuchBeanDefinitionException.","Verify the constructor is public — getConstructor() only returns public members; package-private or private constructors will not be found even with the right parameter types.","Rebuild/redeploy after editing the exception class so the reflective lookup sees the new constructor."],"exampleFix":"// before\npublic class ServiceException extends Exception {\n    public ServiceException(int code) { ... }\n    public ServiceException(String msg, int code) { ... }\n}\n\n// after\npublic class ServiceException extends Exception {\n    public ServiceException(int code) { ... }\n    public ServiceException(String msg, int code) { ... }\n    public ServiceException(String message, Throwable cause) {\n        super(message, cause);\n    }\n    public ServiceException(Throwable cause) {\n        super(cause);\n    }\n}","handlingStrategy":"validation","validationCode":"// Validate the custom exception class BEFORE wiring it into the FactoryBean.\nprivate static void assertValidLocatorException(Class<? extends Exception> exClass) {\n    boolean ok = hasPublicCtor(exClass, String.class, Throwable.class)\n             || hasPublicCtor(exClass, Throwable.class)\n             || hasPublicCtor(exClass, String.class);\n    if (!ok) {\n        throw new IllegalArgumentException(exClass.getName() +\n            \" must declare a public (String, Throwable), (Throwable), or (String) constructor\");\n    }\n}\n\nprivate static boolean hasPublicCtor(Class<?> c, Class<?>... params) {\n    try { c.getConstructor(params); return true; }\n    catch (NoSuchMethodException e) { return false; }\n}","typeGuard":"// Reflective structural guard you can unit-test against the exception class.\nstatic boolean isAcceptableLocatorException(Class<? extends Exception> c) {\n    try { c.getConstructor(String.class, Throwable.class); return true; }\n    catch (NoSuchMethodException ignored) {}\n    try { c.getConstructor(Throwable.class); return true; }\n    catch (NoSuchMethodException ignored) {}\n    try { c.getConstructor(String.class); return true; }\n    catch (NoSuchMethodException ignored) {}\n    return false;\n}","tryCatchPattern":"// setServiceLocatorExceptionClass is invoked during bean init; catch IllegalArgumentException\n// to rethrow as a contextual BeanCreationException, not to silently substitute another class.\ntry {\n    fb.setServiceLocatorExceptionClass(MyException.class);\n} catch (IllegalArgumentException ex) {\n    throw new BeanCreationException(\n        \"Cannot use MyException as service-locator exception: \" + ex.getMessage(), ex);\n}","preventionTips":["Design application exception classes that wrap other throwables with a standard (String message, Throwable cause) constructor from the start — this satisfies Spring and most other frameworks.","Keep a single shared base exception in your domain with the (String, Throwable) and (Throwable) constructors; subclass it for specific cases instead of authoring independent hierarchies.","Write a one-off unit test that calls new ServiceLocatorFactoryBean().setServiceLocatorExceptionClass(MyException.class) against every locator exception class in the codebase.","Prefer omitting setServiceLocatorExceptionClass entirely unless callers genuinely need a checked/domain exception; the default unchecked NoSuchBeanDefinitionException is often acceptable.","When refactoring an exception's constructors, grep for setServiceLocatorExceptionClass and the class name to catch downstream Spring config that depends on the old shape."],"tags":["spring","spring-beans","reflection","exception-handling","configuration","java"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}