{"record":{"id":"61e16e58ed89c415","repo":"apache/hadoop","slug":"reregistration-of-rpckind-rpckind","errorCode":null,"errorMessage":"ReRegistration of rpcKind: ${rpcKind}","messagePattern":"ReRegistration of rpcKind: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java","lineNumber":297,"sourceCode":"\n  /**\n   * Register a RPC kind and the class to deserialize the rpc request.\n   * \n   * Called by static initializers of rpcKind Engines\n   * @param rpcKind - input rpcKind.\n   * @param rpcRequestWrapperClass - this class is used to deserialze the\n   *  the rpc request.\n   * @param rpcInvoker - use to process the calls on SS.\n   */\n  \n  public static void registerProtocolEngine(RPC.RpcKind rpcKind, \n          Class<? extends Writable> rpcRequestWrapperClass,\n          RpcInvoker rpcInvoker) {\n    RpcKindMapValue  old = \n        rpcKindMap.put(rpcKind, new RpcKindMapValue(rpcRequestWrapperClass, rpcInvoker));\n    if (old != null) {\n      rpcKindMap.put(rpcKind, old);\n      throw new IllegalArgumentException(\"ReRegistration of rpcKind: \" +\n          rpcKind);      \n    }\n    LOG.debug(\"rpcKind={}, rpcRequestWrapperClass={}, rpcInvoker={}.\",\n        rpcKind, rpcRequestWrapperClass, rpcInvoker);\n  }\n  \n  public Class<? extends Writable> getRpcRequestWrapper(\n      RpcKindProto rpcKind) {\n    if (rpcRequestClass != null)\n       return rpcRequestClass;\n    RpcKindMapValue val = rpcKindMap.get(ProtoUtil.convert(rpcKind));\n    return (val == null) ? null : val.rpcRequestWrapperClass; \n  }\n\n  protected RpcInvoker getServerRpcInvoker(RPC.RpcKind rpcKind) {\n    return getRpcInvoker(rpcKind);\n  }\n","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java#L279-L315","documentation":"Server.registerProtocolEngine maps an RPC.RpcKind to a request-wrapper class plus RpcInvoker in a static map; registering a kind that already has an entry throws IllegalArgumentException and puts the original mapping back. The framework registers its built-in kinds (RPC_BUILTIN, RPC_WRITABLE, RPC_PROTOCOL_BUFFER) once, so this error always means custom code re-registered an existing kind.","triggerScenarios":"Custom RPC engines calling registerProtocolEngine for an RpcKind already registered — including the built-in RPC_PROTOCOL_BUFFER; registration inside per-instance init or per-test setup that runs twice; static initializers re-executed via class reloading in embedded/OSGi-like containers.","commonSituations":"Third-party protocol-engine integrations; unit tests that construct many servers and register the engine in each setup without a guard; a plugin and service init both registering the same custom kind.","solutions":["Register each RpcKind exactly once per JVM — guard with a static AtomicBoolean/set so repeated init calls are no-ops.","Never re-register the built-in kinds; pick a genuinely distinct RPC.RpcKind for a custom engine.","In tests, register once for the whole suite (@BeforeClass or static block) rather than per test method."],"exampleFix":"// before\npublic void init() {\n  Server.registerProtocolEngine(MY_KIND, MyWrapper.class, myInvoker); // 2nd call throws\n}\n// after\nprivate static final AtomicBoolean REGISTERED = new AtomicBoolean(false);\npublic void init() {\n  if (REGISTERED.compareAndSet(false, true)) {\n    Server.registerProtocolEngine(MY_KIND, MyWrapper.class, myInvoker);\n  }\n}","handlingStrategy":"validation","validationCode":"private static final Set<RPC.RpcKind> REGISTERED_BY_ME =\n    ConcurrentHashMap.newKeySet();\n\nif (REGISTERED_BY_ME.add(rpcKind)) {\n  Server.registerProtocolEngine(rpcKind, wrapperClass, invoker);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat engine registration as one-time static setup, not per-instance or per-test setup.","Never re-register the built-in RpcKinds; use a distinct kind for custom engines.","Design tests to register once per suite and reuse servers, since the rpcKindMap is static."],"tags":["rpc","server","registration","initialization","rpc-kind"],"backgroundTag":"duplicate-registration","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}