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.

Solutions

  1. Add the API module containing the interface to the consumer's dependencies.
  2. Verify the interfaceName fully-qualified name matches the actual class exactly.
  3. 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

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


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/030b237a8520aaf5. Report an issue: GitHub.

Appendix: 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)