alibaba/arthas · error · IllegalArgumentException

{iface} is not an interface

Error message

{iface} is not an interface

What it means

Thrown by ReflectUtils.findInterfaceMethod when the Class passed in is not an interface (iface.isInterface() returns false). The utility enforces a hard precondition: it only inspects interface types via getDeclaredMethods, so concrete classes, abstract classes, arrays, and primitives are rejected up front.

Source

Thrown at common/src/main/java/com/taobao/arthas/common/ReflectUtils.java:409

        for (int i = 0; i < interfaces.length; i++) {
            addAllMethods(interfaces[i], list);
        }

        return list;
    }

    public static List addAllInterfaces(Class type, List list) {
        Class superclass = type.getSuperclass();
        if (superclass != null) {
            list.addAll(Arrays.asList(type.getInterfaces()));
            addAllInterfaces(superclass, list);
        }
        return list;
    }

    public static Method findInterfaceMethod(Class iface) {
        if (!iface.isInterface()) {
            throw new IllegalArgumentException(iface + " is not an interface");
        }
        Method[] methods = iface.getDeclaredMethods();
        if (methods.length != 1) {
            throw new IllegalArgumentException("expecting exactly 1 method in " + iface);
        }
        return methods[0];
    }

    // SPRING PATCH BEGIN
    public static Class defineClass(String className, byte[] b, ClassLoader loader) throws Exception {
        return defineClass(className, b, loader, null, null);
    }

    public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain)
                    throws Exception {

        return defineClass(className, b, loader, protectionDomain, null);
    }

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Pass an interface Class (e.g. Factory.class, or your annotated interface), not a class.
  2. Guard with iface.isInterface() before calling findInterfaceMethod, and pick a different code path for non-interfaces.
  3. Inspect the value of iface logged in the message to confirm what was actually passed.

Example fix

// before
Method m = ReflectUtils.findInterfaceMethod(MyConcreteImpl.class);

// after
if (MyInterface.class.isInterface()) {
    Method m = ReflectUtils.findInterfaceMethod(MyInterface.class);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (iface == null || !iface.isInterface()) {
    // reject before calling findInterfaceMethod
}

Type guard

static boolean isSingleMethodInterface(Class<?> c) {
    return c != null && c.isInterface() && c.getDeclaredMethods().length == 1;
}

Prevention

When it happens

Trigger: Call findInterfaceMethod(class) with a concrete class, abstract class, enum type, array type, or primitive Class object instead of a true Java interface.

Common situations: Accidentally passing a Class<? extends SomeImpl> where an interface type was expected; passing the implementation class of a CGLib factory rather than its interface; tooling that loads arbitrary Class objects and forwards them here.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/38407df2285df509. Report an issue: GitHub.