apache/pulsar · error · RuntimeException

Message payload processor class does not have default constr

Error message

Message payload processor class does not have default constructor

What it means

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.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/MessagePayloadProcessorUtils.java:55

        Class<?> payloadProcessorClass;
        try {
            payloadProcessorClass = ClassLoaderUtils.loadClass(className, classLoader);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(
                    String.format("Failed to load message payload processor class %sx", className));
        }

        try {
            if (configs == null || configs.isEmpty()) {
                Constructor<?> ctor = payloadProcessorClass.getConstructor();
                return (MessagePayloadProcessor) ctor.newInstance();
            } else {
                Constructor<?> ctor = payloadProcessorClass.getConstructor(Map.class);
                return (MessagePayloadProcessor) ctor.newInstance(configs);
            }
        } catch (NoSuchMethodException e) {
            if (configs == null || configs.isEmpty()) {
                throw new RuntimeException("Message payload processor class does not have default constructor", e);
            } else {
                throw new RuntimeException("Message payload processor class does not have constructor accepts map", e);
            }
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
            throw new RuntimeException("Failed to create instance for message payload processor class", e);
        }
    }

    public static MessagePayloadProcessorConfig convertFromSpec(MessagePayloadProcessorSpec spec) {
        if (spec == null || isEmpty(spec.getClassName())) {
            return null;
        }

        MessagePayloadProcessorConfig.MessagePayloadProcessorConfigBuilder bldr =
                MessagePayloadProcessorConfig.builder();

        Type type = new TypeToken<Map<String, Object>>() {
        }.getType();

View on GitHub (pinned to 820761864e)

Solutions

  1. Add a public no-arg constructor to the payload processor class
  2. Or supply a non-empty configs map in the MessagePayloadProcessorSpec so the Map constructor is used
  3. Make the class implement MessagePayloadProcessor and keep a public default constructor per convention

Example fix

// before
public class MyProcessor implements MessagePayloadProcessor {
  public MyProcessor(Map<String,Object> cfg) { ... }
}
// after
public class MyProcessor implements MessagePayloadProcessor {
  public MyProcessor() { }
  public MyProcessor(Map<String,Object> cfg) { ... }
}
Defensive patterns

Strategy: type-guard

Validate before calling

Class<?> c = Class.forName(className, false, cl);
boolean ok;
try { c.getConstructor(); ok = true; } catch (NoSuchMethodException e) { ok = false; }
if (!ok && (configs == null || configs.isEmpty())) {
  throw new IllegalStateException(className + " needs a public no-arg constructor when no configs are set");
}

Type guard

boolean hasDefaultCtor(Class<?> c) {
  try { c.getConstructor(); return true; } catch (NoSuchMethodException e) { return false; }
}

Try / catch

try {
  createFunction(...);
} catch (RuntimeException e) {
  if ("Message payload processor class does not have default constructor".equals(e.getMessage())) {
    log.error("Add a no-arg constructor to {} or provide configs", className);
  }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/4135c16bef0353ac. Report an issue: GitHub.