alibaba/arthas · error · IllegalArgumentException

expecting exactly 1 method in {iface}

Error message

expecting exactly 1 method in {iface}

What it means

Thrown by ReflectUtils.findInterfaceMethod when the passed interface declares zero or more than one method (getDeclaredMethods().length != 1). The helper is built for single-method 'functional' interfaces used by CGLib; multi-method or marker interfaces are rejected because it cannot unambiguously pick the method.

Source

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

        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);
    }

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

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Use a single-method (functional) interface, or split the target into one-method interfaces.
  2. If you need a specific method on a multi-method interface, resolve it by name with Class.getMethod(name, params) instead of findInterfaceMethod.
  3. Check getDeclaredMethods().length on the interface first to validate the precondition.

Example fix

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

// after
Method m = MyMultiMethodApi.class.getMethod("newInstance", argTypes);
Defensive patterns

Strategy: validation

Validate before calling

if (iface == null || !iface.isInterface() || iface.getDeclaredMethods().length != 1) {
    // not a valid single-method interface; do not call findInterfaceMethod
}

Type guard

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

Prevention

When it happens

Trigger: Call findInterfaceMethod(iface) where iface is a marker interface (0 methods), a multi-method interface, or an interface that inherits multiple methods whose declared set on the interface itself is not exactly 1. Note getDeclaredMethods only counts methods declared on this interface, not inherited ones.

Common situations: Passing a multi-method interface like Map or List; passing a marker interface like Serializable or Cloneable; passing a compound interface that combines several functional methods.

Related errors


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