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
- Pass an interface Class (e.g. Factory.class, or your annotated interface), not a class.
- Guard with iface.isInterface() before calling findInterfaceMethod, and pick a different code path for non-interfaces.
- 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
- Always gate calls with iface.isInterface().
- Avoid forwarding arbitrary Class objects from loaders/tooling to this utility.
- Use generics (Class<? extends SomeInterface>) at API boundaries to catch misuse at compile time.
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
- {iface} missing newInstance method
- expecting exactly 1 method in {iface}
- Source is not an array: {}
- Required parameter '{paramName}' cannot be empty
- Cannot convert to char: {value}
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/38407df2285df509.
Report an issue: GitHub.