apache/dubbo · error · IllegalStateException
<t.getMessage()>
Error message
<t.getMessage()>
What it means
Thrown by ServiceConfigBase.getInterfaceClass when the interface class name cannot be loaded via the context ClassLoader (ClassNotFoundException wrapped in IllegalStateException). This is the lazy-resolution path triggered when interfaceClass is null and ref is not a GenericService.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java:283
}
setProtocols(tmpProtocols);
}
}
public Class<?> getInterfaceClass() {
if (interfaceClass != null) {
return interfaceClass;
}
if (ref instanceof GenericService) {
return GenericService.class;
}
try {
if (StringUtils.isNotEmpty(interfaceName)) {
interfaceClass = Class.forName(
interfaceName, true, Thread.currentThread().getContextClassLoader());
}
} catch (ClassNotFoundException t) {
throw new IllegalStateException(t.getMessage(), t);
}
return interfaceClass;
}
/**
* @see #setInterface(Class)
* @deprecated
*/
public void setInterfaceClass(Class<?> interfaceClass) {
setInterface(interfaceClass);
}
public void setInterface(Class<?> interfaceClass) {
this.interfaceClass = interfaceClass;
checkInterface();
setInterface(interfaceClass == null ? null : interfaceClass.getName());
if (getInterfaceClassLoader() == null) {
setInterfaceClassLoader(interfaceClass == null ? null : interfaceClass.getClassLoader());View on GitHub (pinned to 3a3043227f)
Solutions
- Ensure the interface class is on the classpath visible to the thread context ClassLoader.
- Set the interfaceClass explicitly via setInterface(Class) before calling getInterfaceClass().
- Correct the interfaceName to the actual fully-qualified class name.
Example fix
// before
serviceConfig.setInterface("com.example.OldName"); // renamed to NewName
serviceConfig.getInterfaceClass(); // ClassNotFoundException
// after
serviceConfig.setInterface(NewNameService.class); Defensive patterns
Strategy: validation
Validate before calling
// Pre-load the interface via TCCL to fail with a clear message
try {
Class.forName(interfaceName, true, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Interface class not found on classpath: " + interfaceName
+ " — add the API dependency", ex);
}
serviceConfig.getInterfaceClass(); Try / catch
try {
Class<?> c = serviceConfig.getInterfaceClass();
} catch (IllegalStateException e) {
Throwable root = e.getCause() != null ? e.getCause() : e;
throw new RuntimeException("Missing interface class " + serviceConfig.getInterface()
+ ": add the API JAR to the classpath", root);
} Prevention
- Include the interface API module in the provider's dependencies.
- Prefer setInterface(Class) with an already-loaded class over a name string.
- Validate classloader visibility of service interfaces in CI.
When it happens
Trigger: Calling getInterfaceClass() when interfaceClass == null, ref is not a GenericService, interfaceName is non-empty, and Class.forName(interfaceName, true, TCCL) throws ClassNotFoundException.
Common situations: Provider module missing the API JAR that declares the interface. Wrong/stale interfaceName. Context ClassLoader swapped to one that cannot see the interface. Shading/relocation that renamed the interface. Provider and consumer using different classloaders (e.g. OSGi, custom plugin loaders).
Related errors
- <t.getMessage()>
- ${cause.message}
- {} is not visible from class loader
- Error occurred when loading extension class (interface: {},
- {description} cannot be resolved to URL because it does not
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/5346ffc9512ffc78.
Report an issue: GitHub.