{"record":{"id":"27cc7a4a0bfdb41a","repo":"apache/pulsar","slug":"failed-to-create-instance-for-message-payload-proc","errorCode":null,"errorMessage":"Failed to create instance for message payload processor class","messagePattern":"Failed to create instance for message payload processor class","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java","lineNumber":60,"sourceCode":"                    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\n        bldr.className(spec.getClassName()).config(configs);\n\n        return bldr.build();","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java#L42-L78","documentation":"If the constructor is found but newInstance fails — the constructor is inaccessible (IllegalAccessException), the class is abstract/interface (InstantiationException), or the constructor itself throws (InvocationTargetException) — this generic RuntimeException is thrown wrapping the reflective cause.","triggerScenarios":"The payload processor class has the expected constructor, but instantiation fails: class is abstract, constructor is not public, or the constructor body threw an exception (bad config cast, dependency initialization failure).","commonSituations":"Constructor throws NPE/ClassCastException on config values; class declared abstract or only implemented by an interface; constructor not public (package-private after refactor); InvocationTargetException cause chain hiding the real error.","solutions":["Inspect the wrapped cause (getCause()) — for InvocationTargetException the real error is its cause","Make the processor class concrete and its Map/no-arg constructor public","Validate config values inside the constructor or fail fast with a descriptive message before throwing","Initialize external dependencies (clients, clients caches) lazily or defensively in the constructor"],"exampleFix":"// before\nMyProcessor(Map<String,Object> cfg) {\n  this.poolSize = (Integer) cfg.get(\"poolSize\"); // NPE when key missing\n}\n// after\nMyProcessor(Map<String,Object> cfg) {\n  this.poolSize = Integer.parseInt(String.valueOf(cfg.getOrDefault(\"poolSize\", \"4\")));\n}","handlingStrategy":"try-catch","validationCode":"// pre-check: class is concrete and has an accessible constructor\nClass<?> c = Class.forName(className, false, cl);\nif (Modifier.isAbstract(c.getModifiers())) throw new IllegalStateException(className + \" is abstract\");\nc.getConstructor(); // or getConstructor(Map.class) per config mode","typeGuard":null,"tryCatchPattern":"try {\n  createFunction(...);\n} catch (RuntimeException e) {\n  if (\"Failed to create instance for message payload processor class\".equals(e.getMessage())) {\n    // InvocationTargetException wraps the constructor's own exception\n    Throwable root = e;\n    while (root.getCause() != null) root = root.getCause();\n    log.error(\"Processor constructor threw: {}\", root.getMessage(), root);\n  }\n}","preventionTips":["Never throw from processor constructors on partially-valid config — validate lazily","Keep the class concrete (non-abstract) and constructors public","Always unwind getCause() chains: InvocationTargetException hides the real error"],"tags":["pulsar-functions","reflection","instantiation","message-payload-processor"],"backgroundTag":"instantiation-failed","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"}