{"record":{"id":"c96862ee399b6621","repo":"apache/hadoop","slug":"failed-to-get-method","errorCode":null,"errorMessage":"Failed to get method ","messagePattern":"Failed to get method ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java","lineNumber":103,"sourceCode":"    @Override\n    public void handleCallbacks(List<Callback> callbacks, String username, char[] password)\n        throws UnsupportedCallbackException {\n      if (!callbacks.isEmpty()) {\n        final Callback cb = callbacks.get(0);\n        throw new UnsupportedCallbackException(callbacks.get(0),\n            \"Unsupported callback: \" + (cb == null ? null : cb.getClass()));\n      }\n    }\n  }\n\n  static CustomizedCallbackHandler delegate(Object delegated) {\n    final String methodName = \"handleCallbacks\";\n    final Class<?> clazz = delegated.getClass();\n    final Method method;\n    try {\n      method = clazz.getMethod(methodName, List.class, String.class, char[].class);\n    } catch (NoSuchMethodException e) {\n      throw new IllegalStateException(\"Failed to get method \" + methodName + \" from \" + clazz, e);\n    }\n\n    return (callbacks, name, password) -> {\n      try {\n        method.invoke(delegated, callbacks, name, password);\n      } catch (IllegalAccessException | InvocationTargetException e) {\n        throw new IOException(\"Failed to invoke \" + method, e);\n      }\n    };\n  }\n\n  static CustomizedCallbackHandler get(String key, Configuration conf) {\n    return Cache.get(key, conf);\n  }\n\n  void handleCallbacks(List<Callback> callbacks, String name, char[] password)\n      throws UnsupportedCallbackException, IOException;\n}","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java#L85-L121","documentation":"CustomizedCallbackHandler.delegate(Object) adapts any object into the handler interface by reflectively locating a public method named handleCallbacks with the exact signature (List, String, char[]). If no such method exists on the delegated object's class, an IllegalStateException is thrown at adapter-creation time. This is a programming/wiring error: the configured class was instantiated fine but does not expose the expected reflective contract.","triggerScenarios":"Setting hadoop.security.sasl.CustomizedCallbackHandler.class to a class that does NOT implement CustomizedCallbackHandler AND has no public handleCallbacks(List<Callback>, String, char[]) method — Cache.getSynchronously instantiates it and calls CustomizedCallbackHandler.delegate(created), which throws. Also triggered by signature mismatches: wrong parameter types, extra parameters, or a non-public method (getMethod only finds public ones).","commonSituations":"Copy-pasting a handler from an older Hadoop with a different method signature; implementing handleCallbacks with concrete List implementations instead of java.util.List; making the method package-private or static-only; third-party handler jars built against a different branch.","solutions":["Add a public method exactly matching: public void handleCallbacks(java.util.List<javax.security.auth.callback.Callback> callbacks, String username, char[] password)","Alternatively make the class directly implement org.apache.hadoop.security.CustomizedCallbackHandler so the delegate reflection path is never used","Check for accidental overloading (e.g. handleCallbacks(List, String, char[]) plus a legacy handleCallbacks(Callback[], ...)) and ensure the wanted one is public","Redeploy the fixed jar to the server classpath and restart"],"exampleFix":"// before: signature mismatch, getMethod() fails\npublic void handleCallbacks(List<NameCallback> callbacks,\n    String user, char[] pw) { ... }\n\n// after: exact reflective contract\npublic void handleCallbacks(List<Callback> callbacks,\n    String user, char[] pw)\n    throws UnsupportedCallbackException, IOException { ... }","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(configuredHandlerClass);\nboolean implementsIface = CustomizedCallbackHandler.class.isAssignableFrom(c);\nboolean hasReflectiveMethod = false;\ntry {\n  c.getMethod(\"handleCallbacks\", List.class, String.class, char[].class);\n  hasReflectiveMethod = true;\n} catch (NoSuchMethodException ignored) { }\nif (!implementsIface && !hasReflectiveMethod) {\n  throw new IllegalStateException(configuredHandlerClass\n      + \" must implement CustomizedCallbackHandler or expose \"\n      + \"public handleCallbacks(List, String, char[])\");\n}","typeGuard":"static boolean isValidHandlerClass(Class<?> c) {\n  if (CustomizedCallbackHandler.class.isAssignableFrom(c)) return true;\n  try { c.getMethod(\"handleCallbacks\", List.class, String.class, char[].class); return true; }\n  catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  CustomizedCallbackHandler.delegate(target);\n} catch (IllegalStateException e) {\n  // add the public handleCallbacks(List, String, char[]) method\n  // or implement the interface directly\n  LOG.error(\"Handler class lacks handleCallbacks(List,String,char[]): {}\", e.getMessage());\n}","preventionTips":["Match the reflective signature exactly: java.util.List, String, char[], public visibility","Prefer implementing the interface over relying on reflection","Add a config-deployment check that validates the handler class at rollout, before SASL handshakes hit it"],"tags":["sasl","reflection","configuration","callback","hadoop"],"backgroundTag":"reflective-method-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}