apache/hadoop · error · IllegalStateException

Failed to get method

Error message

Failed to get method 

What it means

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.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java:103

    @Override
    public void handleCallbacks(List<Callback> callbacks, String username, char[] password)
        throws UnsupportedCallbackException {
      if (!callbacks.isEmpty()) {
        final Callback cb = callbacks.get(0);
        throw new UnsupportedCallbackException(callbacks.get(0),
            "Unsupported callback: " + (cb == null ? null : cb.getClass()));
      }
    }
  }

  static CustomizedCallbackHandler delegate(Object delegated) {
    final String methodName = "handleCallbacks";
    final Class<?> clazz = delegated.getClass();
    final Method method;
    try {
      method = clazz.getMethod(methodName, List.class, String.class, char[].class);
    } catch (NoSuchMethodException e) {
      throw new IllegalStateException("Failed to get method " + methodName + " from " + clazz, e);
    }

    return (callbacks, name, password) -> {
      try {
        method.invoke(delegated, callbacks, name, password);
      } catch (IllegalAccessException | InvocationTargetException e) {
        throw new IOException("Failed to invoke " + method, e);
      }
    };
  }

  static CustomizedCallbackHandler get(String key, Configuration conf) {
    return Cache.get(key, conf);
  }

  void handleCallbacks(List<Callback> callbacks, String name, char[] password)
      throws UnsupportedCallbackException, IOException;
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Add a public method exactly matching: public void handleCallbacks(java.util.List<javax.security.auth.callback.Callback> callbacks, String username, char[] password)
  2. Alternatively make the class directly implement org.apache.hadoop.security.CustomizedCallbackHandler so the delegate reflection path is never used
  3. Check for accidental overloading (e.g. handleCallbacks(List, String, char[]) plus a legacy handleCallbacks(Callback[], ...)) and ensure the wanted one is public
  4. Redeploy the fixed jar to the server classpath and restart

Example fix

// before: signature mismatch, getMethod() fails
public void handleCallbacks(List<NameCallback> callbacks,
    String user, char[] pw) { ... }

// after: exact reflective contract
public void handleCallbacks(List<Callback> callbacks,
    String user, char[] pw)
    throws UnsupportedCallbackException, IOException { ... }
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(configuredHandlerClass);
boolean implementsIface = CustomizedCallbackHandler.class.isAssignableFrom(c);
boolean hasReflectiveMethod = false;
try {
  c.getMethod("handleCallbacks", List.class, String.class, char[].class);
  hasReflectiveMethod = true;
} catch (NoSuchMethodException ignored) { }
if (!implementsIface && !hasReflectiveMethod) {
  throw new IllegalStateException(configuredHandlerClass
      + " must implement CustomizedCallbackHandler or expose "
      + "public handleCallbacks(List, String, char[])");
}

Type guard

static boolean isValidHandlerClass(Class<?> c) {
  if (CustomizedCallbackHandler.class.isAssignableFrom(c)) return true;
  try { c.getMethod("handleCallbacks", List.class, String.class, char[].class); return true; }
  catch (NoSuchMethodException e) { return false; }
}

Try / catch

try {
  CustomizedCallbackHandler.delegate(target);
} catch (IllegalStateException e) {
  // add the public handleCallbacks(List, String, char[]) method
  // or implement the interface directly
  LOG.error("Handler class lacks handleCallbacks(List,String,char[]): {}", e.getMessage());
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/c96862ee399b6621. Report an issue: GitHub.