{"record":{"id":"83a3971f65b411cf","repo":"alibaba/arthas","slug":"iface-missing-newinstance-method","errorCode":null,"errorMessage":"{iface} missing newInstance method","messagePattern":"(.+?) missing newInstance method","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/taobao/arthas/common/ReflectUtils.java","lineNumber":314,"sourceCode":"        String[] names = new String[classes.length];\n        for (int i = 0; i < names.length; i++) {\n            names[i] = classes[i].getName();\n        }\n        return names;\n    }\n\n    public static Class[] getClasses(Object[] objects) {\n        Class[] classes = new Class[objects.length];\n        for (int i = 0; i < objects.length; i++) {\n            classes[i] = objects[i].getClass();\n        }\n        return classes;\n    }\n\n    public static Method findNewInstance(Class iface) {\n        Method m = findInterfaceMethod(iface);\n        if (!m.getName().equals(\"newInstance\")) {\n            throw new IllegalArgumentException(iface + \" missing newInstance method\");\n        }\n        return m;\n    }\n\n    public static Method[] getPropertyMethods(PropertyDescriptor[] properties, boolean read, boolean write) {\n        Set methods = new HashSet();\n        for (int i = 0; i < properties.length; i++) {\n            PropertyDescriptor pd = properties[i];\n            if (read) {\n                methods.add(pd.getReadMethod());\n            }\n            if (write) {\n                methods.add(pd.getWriteMethod());\n            }\n        }\n        methods.remove(null);\n        return (Method[]) methods.toArray(new Method[methods.size()]);\n    }","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/common/src/main/java/com/taobao/arthas/common/ReflectUtils.java#L296-L332","documentation":"Thrown by ReflectUtils.findNewInstance when the supplied interface's single declared method is NOT named 'newInstance'. findNewInstance first resolves the interface's sole method via findInterfaceMethod, then asserts the method name equals 'newInstance' — this assert fails. It is a CGLib-style factory-interface contract: the interface is expected to declare exactly one factory method named newInstance.","triggerScenarios":"Call ReflectUtils.findNewInstance(iface) where iface is a single-method interface but its method has any name other than 'newInstance' (e.g. a Supplier, Callable, or custom factory interface with methods like create/build/apply).","commonSituations":"Passing a Java standard functional interface (Supplier, Function, Consumer) or a user-defined factory interface to a code path that expects a CGLib Factory/newInstance interface. Using ReflectUtils as a generic reflection helper when it was written specifically for cglib Enhancer factory generation.","solutions":["Pass a single-method interface whose method is literally named 'newInstance' (the CGLib Factory convention).","If you only need to invoke the interface's method, call findInterfaceMethod(iface) directly instead of findNewInstance.","If you need a generic single-method invoker, write your own helper that resolves the declared method without the newInstance name check."],"exampleFix":"// before\nMethod m = ReflectUtils.findNewInstance(MyFactory.class); // MyFactory has create()\n\n// after (use the generic interface-method resolver)\nMethod m = ReflectUtils.findInterfaceMethod(MyFactory.class);\n// or rename MyFactory's method to newInstance","handlingStrategy":"validation","validationCode":"Method sole = iface.isInterface() && iface.getDeclaredMethods().length == 1 ? iface.getDeclaredMethods()[0] : null;\nif (sole == null || !\"newInstance\".equals(sole.getName())) {\n    // do not call ReflectUtils.findNewInstance(iface); pick another path\n}","typeGuard":"static boolean isFactoryInterface(Class<?> iface) {\n    if (iface == null || !iface.isInterface()) return false;\n    Method[] ms = iface.getDeclaredMethods();\n    return ms.length == 1 && \"newInstance\".equals(ms[0].getName());\n}","tryCatchPattern":null,"preventionTips":["Only pass CGLib-style single-method interfaces whose method is named newInstance.","Prefer findInterfaceMethod for generic single-method resolution without the name check.","Document at call sites that findNewInstance implies the newInstance naming contract."],"tags":["reflection","cglib","api-contract"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}