{"record":{"id":"b711e930670705cd","repo":"apache/pulsar","slug":"message-payload-processor-class-does-not-have-cons","errorCode":null,"errorMessage":"Message payload processor class does not have constructor accepts map","messagePattern":"Message payload processor class does not have constructor accepts map","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java","lineNumber":57,"sourceCode":"            payloadProcessorClass = ClassLoaderUtils.loadClass(className, classLoader);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\n                    String.format(\"Failed to load message payload processor class %sx\", className));\n        }\n\n        try {\n            if (configs == null || configs.isEmpty()) {\n                Constructor<?> ctor = payloadProcessorClass.getConstructor();\n                return (MessagePayloadProcessor) ctor.newInstance();\n            } else {\n                Constructor<?> ctor = payloadProcessorClass.getConstructor(Map.class);\n                return (MessagePayloadProcessor) ctor.newInstance(configs);\n            }\n        } catch (NoSuchMethodException e) {\n            if (configs == null || configs.isEmpty()) {\n                throw new RuntimeException(\"Message payload processor class does not have default constructor\", e);\n            } else {\n                throw new RuntimeException(\"Message payload processor class does not have constructor accepts map\", e);\n            }\n        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {\n            throw new RuntimeException(\"Failed to create instance for message payload processor class\", e);\n        }\n    }\n\n    public static MessagePayloadProcessorConfig convertFromSpec(MessagePayloadProcessorSpec spec) {\n        if (spec == null || isEmpty(spec.getClassName())) {\n            return null;\n        }\n\n        MessagePayloadProcessorConfig.MessagePayloadProcessorConfigBuilder bldr =\n                MessagePayloadProcessorConfig.builder();\n\n        Type type = new TypeToken<Map<String, Object>>() {\n        }.getType();\n        Map<String, Object> configs = new Gson().fromJson(spec.getConfigs(), type);\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java#L39-L75","documentation":"Mirror case of the missing default constructor: when a non-empty configs map is supplied, getMessagePayloadProcessorInstance looks for a constructor accepting Map; a NoSuchMethodException there is rethrown as this RuntimeException.","triggerScenarios":"Function spec passes non-empty configs for messagePayloadProcessor, but the processor class has no public constructor taking a single Map argument (only a default constructor, or a different signature).","commonSituations":"Configs added in the function spec after the class was written with only a no-arg constructor; config keys passed as a Map<String,String> expectation mismatch (signature must be Map.class); wrong class configured.","solutions":["Add a public constructor accepting java.util.Map to the processor class","Or remove/clear the configs in the spec so the no-arg constructor path is used","Ensure the constructor's parameter is exactly Map (getConstructor(Map.class)) — not a subtype or different generic erasure"],"exampleFix":"// before\npublic MyProcessor() { }\n// after\npublic MyProcessor(Map<String, Object> configs) {\n  this.timeoutMs = (int) configs.getOrDefault(\"timeoutMs\", 30000);\n}","handlingStrategy":"type-guard","validationCode":"Class<?> c = Class.forName(className, false, cl);\nboolean ok;\ntry { c.getConstructor(Map.class); ok = true; } catch (NoSuchMethodException e) { ok = false; }\nif (!ok && configs != null && !configs.isEmpty()) {\n  throw new IllegalStateException(className + \" needs a public Map constructor when configs are set\");\n}","typeGuard":"boolean hasMapCtor(Class<?> c) {\n  try { c.getConstructor(Map.class); return true; } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  createFunction(...);\n} catch (RuntimeException e) {\n  if (\"Message payload processor class does not have constructor accepts map\".equals(e.getMessage())) {\n    log.error(\"Add MyProcessor(Map<String,Object>) to {}\", className);\n  }\n}","preventionTips":["Use exactly java.util.Map as the constructor parameter type (erasure must match Map.class)","When adding configs to the spec, verify the processor supports them","Unit-test instantiation with a sample configs map"],"tags":["pulsar-functions","reflection","constructor","message-payload-processor"],"backgroundTag":"missing-constructor","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}