{"record":{"id":"c865c0d04afdb517","repo":"ssssssss-team/spider-flow","slug":"couldn-t-call-method-javamethod-getname","errorCode":null,"errorMessage":"Couldn't call method '\" + javaMethod.getName() + \"' with arguments '\" + Arrays.toString(arguments) + \"' on object of type '\" + obj.getClass().getSimpleName() + \"'.","messagePattern":"Couldn't call method '\" \\+ javaMethod\\.getName\\(\\) \\+ \"' with arguments '\" \\+ Arrays\\.toString\\(arguments\\) \\+ \"' on object of type '\" \\+ obj\\.getClass\\(\\)\\.getSimpleName\\(\\) \\+ \"'\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spider-flow-core/src/main/java/org/spiderflow/core/expression/interpreter/JavaReflection.java","lineNumber":326,"sourceCode":"\n\t\tif (from == Long.class || from == long.class) {\n\t\t\treturn to == float.class || to == Float.class || to == double.class || to == Double.class;\n\t\t}\n\t\t\n\t\tif(from == int[].class || from == Integer[].class){\n\t\t\treturn to == Object[].class || to == float[].class || to == Float[].class || to == double[].class || to == Double[].class || to == long[].class || to == Long[].class;\n\t\t}\n\t\t\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic Object callMethod (Object obj, Object method, Object... arguments) {\n\t\tMethod javaMethod = (Method)method;\n\t\ttry {\n\t\t\treturn javaMethod.invoke(obj, arguments);\n\t\t} catch (Throwable t) {\n\t\t\tthrow new RuntimeException(\"Couldn't call method '\" + javaMethod.getName() + \"' with arguments '\" + Arrays.toString(arguments)\n\t\t\t\t+ \"' on object of type '\" + obj.getClass().getSimpleName() + \"'.\", t);\n\t\t}\n\t}\n\n\tprivate static class MethodSignature {\n\t\tprivate final String name;\n\t\t@SuppressWarnings(\"rawtypes\") private final Class[] parameters;\n\t\tprivate final int hashCode;\n\n\t\t@SuppressWarnings(\"rawtypes\")\n\t\tpublic MethodSignature (String name, Class[] parameters) {\n\t\t\tthis.name = name;\n\t\t\tthis.parameters = parameters;\n\t\t\tfinal int prime = 31;\n\t\t\tint hash = 1;\n\t\t\thash = prime * hash + ((name == null) ? 0 : name.hashCode());\n\t\t\thash = prime * hash + Arrays.hashCode(parameters);\n\t\t\thashCode = hash;","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/ssssssss-team/spider-flow/blob/c799cca99c7d064673dc79e6ef06a08bbc0e292d/spider-flow-core/src/main/java/org/spiderflow/core/expression/interpreter/JavaReflection.java#L308-L344","documentation":"JavaReflection.callMethod invokes a reflective Method with the given arguments via Method.invoke. Any failure (IllegalAccessException, IllegalArgumentException, InvocationTargetException from the method body itself) is rethrown as a RuntimeException describing the method, its arguments, and the target object's class, with the original throwable as cause.","triggerScenarios":"Calling callMethod(obj, method, args...) during expression evaluation when the target method throws, the arguments don't match the signature, or the method is inaccessible.","commonSituations":"Invoking user-configured methods in spider expressions with wrong argument types/counts; invoking a method that itself throws a business exception; reflective access blocked by module rules.","solutions":["Inspect getCause() of the RuntimeException: InvocationTargetException means the target method itself threw — fix the method logic or its inputs","Verify argument count and types exactly match the Method signature (boxed primitives count)","Ensure the method is accessible (public, or setAccessible(true))","Check the target object is not null and is an instance of the declaring class"],"exampleFix":"// before\nObject r = reflection.callMethod(obj, method, args);\n// after\ntry {\n    Object r = reflection.callMethod(obj, method, args);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof InvocationTargetException && cause.getCause() != null) {\n        throw (RuntimeException) cause.getCause(); // real business error\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (obj == null || !((Method) method).getDeclaringClass().isInstance(obj)) {\n    throw new IllegalArgumentException(\"Target object incompatible with method\");\n}\nif (((Method) method).getParameterCount() != arguments.length) {\n    throw new IllegalArgumentException(\"Argument count mismatch for method \" + method);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return reflection.callMethod(obj, method, arguments);\n} catch (RuntimeException e) {\n    Throwable root = e.getCause();\n    if (root instanceof InvocationTargetException && root.getCause() != null) {\n        throw new ExpressionEvaluationException(\"Method threw: \" + root.getCause().getMessage(), root.getCause());\n    }\n    throw new ExpressionEvaluationException(\"Cannot invoke method: \" + e.getMessage(), e);\n}","preventionTips":["Unwrap InvocationTargetException to see the real business exception in the cause chain","Match argument types exactly (boxing matters: int vs Integer)","Keep invoked methods public and classes public","Unit-test method calls used in expressions with representative arguments"],"tags":["reflection","java","method-invocation"],"backgroundTag":"reflection-access-failed","analyzedSha":"c799cca99c7d064673dc79e6ef06a08bbc0e292d","analyzedAt":"2026-09-08T13:47:08.225Z","contentChangedAt":"2026-09-08T13:47:08.225Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}