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

  1. Ensure the interface class is on the classpath visible to the thread context ClassLoader.
  2. Set the interfaceClass explicitly via setInterface(Class) before calling getInterfaceClass().
  3. 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

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


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