apache/dubbo · error · IllegalStateException
<t.getMessage()>
Error message
<t.getMessage()>
What it means
Thrown by ReferenceConfigBase.determineInterfaceClass when the interface class name cannot be loaded by the given ClassLoader (ClassNotFoundException wrapped in IllegalStateException). This is the non-generic path: the interfaceName is non-empty but the class is absent from the classloader used to resolve it.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java:242
* @param interfaceName
* @return
*/
public static Class<?> determineInterfaceClass(String generic, String interfaceName) {
return determineInterfaceClass(generic, interfaceName, ClassUtils.getClassLoader());
}
public static Class<?> determineInterfaceClass(String generic, String interfaceName, ClassLoader classLoader) {
if (ProtocolUtils.isGeneric(generic)) {
return Dubbo2CompactUtils.isEnabled() && Dubbo2CompactUtils.isGenericServiceClassLoaded()
? Dubbo2CompactUtils.getGenericServiceClass()
: GenericService.class;
}
try {
if (StringUtils.isNotEmpty(interfaceName)) {
return Class.forName(interfaceName, true, classLoader);
}
} catch (ClassNotFoundException t) {
throw new IllegalStateException(t.getMessage(), t);
}
return null;
}
@Override
protected void postProcessAfterScopeModelChanged(ScopeModel oldScopeModel, ScopeModel newScopeModel) {
super.postProcessAfterScopeModelChanged(oldScopeModel, newScopeModel);
if (this.consumer != null && this.consumer.getScopeModel() != getScopeModel()) {
this.consumer.setScopeModel(getScopeModel());
}
}
public void setInterface(Class<?> interfaceClass) {
if (interfaceClass != null && !interfaceClass.isInterface()) {
throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
}
setInterface(interfaceClass == null ? null : interfaceClass.getName());
this.interfaceClass = interfaceClass;View on GitHub (pinned to 3a3043227f)
Solutions
- Add the API module containing the interface to the consumer's dependencies.
- Verify the interfaceName fully-qualified name matches the actual class exactly.
- Ensure the ClassLoader passed in (or the TCCL) can see the interface class.
Example fix
// before
// consumer module is missing the api.jar that declares com.example.FooService
ReferenceConfig<FooService> ref = new ReferenceConfig<>();
ref.setInterface("com.example.FooService");
// after
// add the api module dependency, then:
ref.setInterface(FooService.class); Defensive patterns
Strategy: validation
Validate before calling
// Verify the interface is loadable before constructing the reference
Class<?> iface;
try {
iface = Class.forName(interfaceName, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new IllegalStateException("Interface not on classpath: " + interfaceName
+ " — add the API dependency", ex);
}
Class<?> determined = ReferenceConfigBase.determineInterfaceClass(generic, interfaceName, classLoader); Try / catch
try {
Class<?> c = ReferenceConfigBase.determineInterfaceClass(generic, interfaceName, loader);
} catch (IllegalStateException e) {
Throwable root = e.getCause() != null ? e.getCause() : e;
// root is ClassNotFoundException; surface a clear 'missing dependency' message
throw new RuntimeException("Missing interface class " + interfaceName
+ ": ensure the API JAR is on the classpath", root);
} Prevention
- Add the interface API module as a dependency to consumer modules.
- Validate classpath completeness in CI before integration tests.
- Pass an already-loaded Class via setInterface(Class) when available.
When it happens
Trigger: Calling determineInterfaceClass(generic, interfaceName, classLoader) where interfaceName is set, generic is not a generic-serialization type, and Class.forName(interfaceName, true, classLoader) throws ClassNotFoundException.
Common situations: Interface class not on the consumer's classpath (missing dependency JAR). Wrong or stale interfaceName string. Custom ClassLoader that does not expose the interface class. Fat-jar/shading that relocated or omitted the interface. Multi-module build where the API module isn't a dependency of the consumer.
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/030b237a8520aaf5.
Report an issue: GitHub.