{"record":{"id":"9239a8d6a19dccb3","repo":"apache/hadoop","slug":"the-proxies-specified-for-combinedproxyinterface","errorCode":null,"errorMessage":"The proxies specified for ${combinedProxyInterface} do not cover method ${method}","messagePattern":"The proxies specified for (.+?) do not cover method (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProxyCombiner.java","lineNumber":75,"sourceCode":"   * @param combinedProxyInterface The interface of the combined proxy.\n   * @param proxies The proxies which should be used as delegates.\n   * @param <T> The type of the proxy that will be returned.\n   * @return The combined proxy.\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T combine(Class<T> combinedProxyInterface,\n      Object... proxies) {\n    methodLoop:\n    for (Method m : combinedProxyInterface.getMethods()) {\n      for (Object proxy : proxies) {\n        try {\n          proxy.getClass().getMethod(m.getName(), m.getParameterTypes());\n          continue methodLoop; // go to the next method\n        } catch (NoSuchMethodException nsme) {\n          // Continue to try the next proxy\n        }\n      }\n      throw new IllegalStateException(\"The proxies specified for \"\n          + combinedProxyInterface + \" do not cover method \" + m);\n    }\n\n    InvocationHandler handler =\n        new CombinedProxyInvocationHandler(combinedProxyInterface, proxies);\n    return (T) Proxy.newProxyInstance(combinedProxyInterface.getClassLoader(),\n        new Class[] {combinedProxyInterface}, handler);\n  }\n\n  private static final class CombinedProxyInvocationHandler\n      implements RpcInvocationHandler {\n\n    private final Class<?> proxyInterface;\n    private final Object[] proxies;\n\n    private CombinedProxyInvocationHandler(Class<?> proxyInterface,\n        Object[] proxies) {\n      this.proxyInterface = proxyInterface;","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProxyCombiner.java#L57-L93","documentation":"ProxyCombiner.combine builds one dynamic proxy implementing combinedProxyInterface by delegating each method to one of the given backing proxies. Before creating it, it verifies coverage: every method declared on combinedProxyInterface must exist (by name and parameter types) on at least one backing proxy; the first uncovered method triggers IllegalStateException naming the interface and method. This is a fail-fast wiring check, usually hit while assembling HA-style composite proxies at startup.","triggerScenarios":"Calling RPC.waitForProtocolProxy / combining proxies (e.g., HAServiceProtocol + ZKFC-style composites) where one backing proxy class lacks a method present on the combined interface; passing proxies in the wrong order for interfaces with overlapping names but different signatures; adding a method to the combined interface without updating a constituent translator.","commonSituations":"Custom HA client setups assembling combined protocol proxies; refactors of protocolPB translators where a method was renamed or dropped; tests stubbing one of the proxies with Mockito and losing the method.","solutions":["Ensure every method of the combined interface (exact name + parameter types) exists on at least one passed proxy.","Add or restore the missing method on the backing proxy/translator (keep signatures identical, including parameter types).","If the combined interface gained methods, update all constituent proxies in the same change."],"exampleFix":"// before\ninterface Refresh extends RefreshProtocol, RefreshAdminProtocol {}\nRefresh combined = (Refresh) ProxyCombiner.combine(Refresh.class,\n    refreshProxy); // RefreshAdminProtocol methods uncovered -> IllegalStateException\n\n// after\nRefresh combined = (Refresh) ProxyCombiner.combine(Refresh.class,\n    refreshProxy, refreshAdminProxy); // every method covered","handlingStrategy":"validation","validationCode":"// verify coverage before combine()\nouter:\nfor (Method m : combinedInterface.getMethods()) {\n  for (Object p : proxies) {\n    try { p.getClass().getMethod(m.getName(), m.getParameterTypes()); continue outer; }\n    catch (NoSuchMethodException ignored) { }\n  }\n  throw new IllegalStateException(\"No proxy covers \" + m + \" - add the missing backing proxy\");\n}\nreturn ProxyCombiner.combine(combinedInterface, proxies);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When adding a method to a combined interface, update constituent translators in the same commit.","Keep combined-interface methods exact-signature-compatible (name + parameter types) with the backing proxies.","Add the pre-combine coverage check above as a unit test for composite proxy wiring."],"tags":["hadoop","ipc","rpc","proxy","reflection","wiring"],"backgroundTag":"proxy-interface-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}