apache/dubbo · error · RuntimeException

{} is not a interface.

Error message

{} is not a interface.

What it means

Thrown by Proxy.buildInterfacesKey when one of the classes passed to getProxy is not an interface. Dubbo proxies implement interfaces only (it generates an implementor, not a subclass), so a concrete/abstract class is rejected with RuntimeException naming the class.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java:100

        if (proxy == null) {
            synchronized (ics[0]) {
                proxy = cache.get(key);
                if (proxy == null) {
                    // create Proxy class.
                    proxy = new Proxy(buildProxyClass(cl, ics, domain));
                    cache.put(key, proxy);
                }
            }
        }
        return proxy;
    }

    private static String buildInterfacesKey(ClassLoader cl, Class<?>[] ics) {
        StringBuilder sb = new StringBuilder();
        for (Class<?> ic : ics) {
            String itf = ic.getName();
            if (!ic.isInterface()) {
                throw new RuntimeException(itf + " is not a interface.");
            }

            Class<?> tmp = null;
            try {
                tmp = Class.forName(itf, false, cl);
            } catch (ClassNotFoundException ignore) {
            }

            if (tmp != ic) {
                throw new IllegalArgumentException(ic + " is not visible from class loader");
            }

            sb.append(itf).append(';');
        }
        return sb.toString();
    }

    private static Class<?> buildProxyClass(ClassLoader cl, Class<?>[] ics, ProtectionDomain domain) {

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Pass only interface types to getProxy.
  2. If you must proxy a concrete class, use a different proxying library (CGLIB) - Dubbo's Proxy is interface-only.
  3. Add a pre-check ic.isInterface() for each class before calling getProxy.

Example fix

// before
Proxy.getProxy(MyServiceImpl.class); // class, not interface

// after
Proxy.getProxy(MyService.class); // interface
Defensive patterns

Strategy: validation

Validate before calling

for (Class<?> ic : ics) {
    if (!ic.isInterface()) {
        throw new IllegalArgumentException(ic.getName() + " is not an interface");
    }
}
Proxy.getProxy(ics);

Prevention

When it happens

Trigger: Proxy.getProxy(SomeClass.class, ...) where SomeClass is not declared as an interface.

Common situations: Passing an implementation class instead of its interface; a type that was refactored from interface to class; misconfigured SPI that hands a class to the proxy factory.

Related errors


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