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

  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.