apache/pulsar · error · RuntimeException
Key reader class does not have constructor accepts map
Error message
Key reader class does not have constructor accepts map
What it means
After the CryptoKeyReader class is loaded, CryptoUtils requires a public constructor accepting a single Map (of configs) to instantiate it. If the class has no Map-argument constructor (NoSuchMethodException), this RuntimeException with cause is thrown. This is an SPI convention: crypto key reader implementations must expose CryptoKeyReader(Map<String,Object> configs).
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/CryptoUtils.java:105
return bldr.build();
}
public static CryptoKeyReader getCryptoKeyReaderInstance(String className, Map<String, Object> configs,
ClassLoader classLoader) {
Class<?> cryptoClass;
try {
cryptoClass = ClassLoaderUtils.loadClass(className, classLoader);
} catch (ClassNotFoundException e) {
throw new RuntimeException(
String.format("Failed to load crypto key reader class %sx", className));
}
try {
Constructor<?> ctor = cryptoClass.getConstructor(Map.class);
return (CryptoKeyReader) ctor.newInstance(configs);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Key reader class does not have constructor accepts map", e);
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new RuntimeException("Failed to create instance for key reader class", e);
}
}
public static ProducerCryptoFailureAction getProducerCryptoFailureAction(CryptoSpec.FailureAction action) {
switch (action) {
case FAIL:
return ProducerCryptoFailureAction.FAIL;
case SEND:
return ProducerCryptoFailureAction.SEND;
default:
throw new RuntimeException(
"Unknown producer protobuf failure action " + action.name());
}
}
public static ConsumerCryptoFailureAction getConsumerCryptoFailureAction(CryptoSpec.FailureAction action) {View on GitHub (pinned to 820761864e)
Solutions
- Add a public constructor taking Map<String,Object> (raw Map parameter per getConstructor(Map.class)) to your CryptoKeyReader implementation
- If the class cannot be changed, wrap it in an adapter class with the required Map constructor
- Confirm the constructor is public and takes exactly one java.util.Map parameter (not a subtype or Object)
Example fix
// before
class MyKeyReader implements CryptoKeyReader {
public MyKeyReader() { }
...
}
// after
class MyKeyReader implements CryptoKeyReader {
public MyKeyReader(Map<String, Object> configs) {
// initialize from configs
}
...
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = ClassLoaderUtils.loadClass(className, classLoader);
boolean hasMapCtor = false;
for (Constructor<?> ctor : c.getConstructors()) {
if (ctor.getParameterCount() == 1 && ctor.getParameterTypes()[0] == Map.class) { hasMapCtor = true; }
}
if (!hasMapCtor) throw new IllegalStateException(className + " needs a public Map-arg constructor"); Try / catch
try {
CryptoKeyReader reader = CryptoUtils.getCryptoKeyReaderInstance(className, configs, classLoader);
} catch (RuntimeException e) {
if (e.getMessage().contains("constructor accepts map")) { /* add CryptoKeyReader(Map) constructor */ }
} Prevention
- Follow the SPI convention: implement a public CryptoKeyReader(Map<String,Object>) constructor
- Unit-test instantiation of custom crypto classes via reflection before deploying
- Document the required constructor in your client crypto config templates
When it happens
Trigger: A custom CryptoKeyReader class exists on the classpath but only defines a no-arg constructor (or default constructor only), while getCryptoKeyReaderInstance calls cryptoClass.getConstructor(Map.class).
Common situations: implementations written against older examples using a no-arg constructor; refactoring that removed the Map constructor; implementing CryptoKeyReader in Kotlin/Scala without generating the Map-arg constructor.
Related errors
- The crypto key reader class %s does not implement the desire
- User class must have a no-arg constructor
- User class constructor throws exception
- User class doesn't have such method
- User class doesn't have such method
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8fec273cb07a8e2b.
Report an issue: GitHub.