{"record":{"id":"4135c16bef0353ac","repo":"apache/pulsar","slug":"message-payload-processor-class-does-not-have-defa","errorCode":null,"errorMessage":"Message payload processor class does not have default constructor","messagePattern":"Message payload processor class does not have default constructor","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java","lineNumber":55,"sourceCode":"        Class<?> payloadProcessorClass;\n        try {\n            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();","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java#L37-L73","documentation":"After loading the payload processor class, the code instantiates it reflectively: with no configs it looks for a no-arg constructor. If getConstructor() throws NoSuchMethodException (and configs is empty/null), this RuntimeException is thrown.","triggerScenarios":"Registering/running a function whose payload processor has an empty (null/empty map) config set but the class only defines a constructor taking Map<String,Object> (or any other signature).","commonSituations":"Class written expecting configuration, but no config supplied in the function spec; class refactored to remove the default constructor; copy-pasted class that only has the Map constructor.","solutions":["Add a public no-arg constructor to the payload processor class","Or supply a non-empty configs map in the MessagePayloadProcessorSpec so the Map constructor is used","Make the class implement MessagePayloadProcessor and keep a public default constructor per convention"],"exampleFix":"// before\npublic class MyProcessor implements MessagePayloadProcessor {\n  public MyProcessor(Map<String,Object> cfg) { ... }\n}\n// after\npublic class MyProcessor implements MessagePayloadProcessor {\n  public MyProcessor() { }\n  public MyProcessor(Map<String,Object> cfg) { ... }\n}","handlingStrategy":"type-guard","validationCode":"Class<?> c = Class.forName(className, false, cl);\nboolean ok;\ntry { c.getConstructor(); ok = true; } catch (NoSuchMethodException e) { ok = false; }\nif (!ok && (configs == null || configs.isEmpty())) {\n  throw new IllegalStateException(className + \" needs a public no-arg constructor when no configs are set\");\n}","typeGuard":"boolean hasDefaultCtor(Class<?> c) {\n  try { c.getConstructor(); 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 default constructor\".equals(e.getMessage())) {\n    log.error(\"Add a no-arg constructor to {} or provide configs\", className);\n  }\n}","preventionTips":["Always provide a public no-arg constructor in payload processor classes","If the class needs config, ensure the spec supplies non-empty configs","Add a unit test that instantiates the processor via reflection the same way the worker does"],"tags":["pulsar-functions","reflection","constructor","message-payload-processor"],"backgroundTag":"missing-default-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"}