apache/pulsar · error · RuntimeException
User class must have a no-arg constructor
Error message
User class must have a no-arg constructor
What it means
After locating the extractor's no-arg constructor, newInstance() is invoked reflectively. If the constructor is non-public (or the class/constructor is otherwise inaccessible from the executor), IllegalAccessException is rethrown as "User class must have a no-arg constructor". setAccessible(true) mitigates some cases, but inaccessible constructors in restricted contexts still throw. The extractor needs an accessible no-arg constructor.
Source
Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java:152
theCls = Class.forName(windowConfig.getTimestampExtractorClassName(),
true, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException | NoClassDefFoundError cnfe) {
throw new RuntimeException(
String.format("Timestamp extractor class %s must be in class path",
windowConfig.getTimestampExtractorClassName()), cnfe);
}
Object result;
try {
Constructor<?> constructor = theCls.getDeclaredConstructor();
constructor.setAccessible(true);
result = constructor.newInstance();
} catch (InstantiationException ie) {
throw new RuntimeException("User class must be concrete", ie);
} catch (NoSuchMethodException e) {
throw new RuntimeException("User class doesn't have such method", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("User class must have a no-arg constructor", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("User class constructor throws exception", e);
}
Class<?>[] timestampExtractorTypeArgs = TypeResolver.resolveRawArguments(
TimestampExtractor.class, result.getClass());
Class<?>[] typeArgs = TypeResolver.resolveRawArguments(Function.class, this.getClass());
if (!typeArgs[0].equals(timestampExtractorTypeArgs[0])) {
throw new RuntimeException(
"Inconsistent types found between function input type and timestamp extractor type: "
+ " function type = " + typeArgs[0] + ", timestamp extractor type = "
+ timestampExtractorTypeArgs[0]);
}
return (TimestampExtractor<T>) result;
}
private TriggerPolicy<Record<T>, ?> getTriggerPolicy(WindowConfig windowConfig, WindowManager<Record<T>> manager,
EvictionPolicy<Record<T>, ?> evictionPolicy, Context context) {
if (windowConfig.getSlidingIntervalCount() != null) {View on GitHub (pinned to 820761864e)
Solutions
- Make the no-arg constructor public
- Avoid placing the extractor behind JPMS strong encapsulation or add the necessary --add-opens
- Verify the class isn't a private nested class; move it to a top-level or public static nested class
- Rebuild and redeploy the function
Example fix
// before
public class MyExtractor implements TimestampExtractor<String> {
private MyExtractor() { }
}
// after
public class MyExtractor implements TimestampExtractor<String> {
public MyExtractor() { }
} Defensive patterns
Strategy: validation
Validate before calling
Constructor<?> ctor = Class.forName(className).getDeclaredConstructor();
if (!Modifier.isPublic(ctor.getModifiers())) {
throw new IllegalStateException("extractor no-arg constructor must be public: " + className);
}
ctor.setAccessible(true); ctor.newInstance(); // verify instantiability Try / catch
try {
executor.initialize();
} catch (RuntimeException e) {
if ("User class must have a no-arg constructor".equals(e.getMessage())) {
throw new IllegalStateException("make the extractor constructor public and top-level", e);
}
throw e;
} Prevention
- Make extractor classes public and non-nested (or public static nested)
- Avoid JPMS encapsulation around extractor packages in function runtimes
- Instantiate the extractor once in a unit test before deployment
When it happens
Trigger: Constructor is private/package-private and security manager or module restrictions block setAccessible; getDeclaredConstructor finds the constructor but newInstance cannot invoke it.
Common situations: Extractors written with private singletons; Java module (JPMS) boundaries blocking reflective access; class defined in a package the function instance cannot open reflectively.
Related errors
- User class must be concrete
- User class doesn't have such method
- User class constructor throws exception
- User class must have a public constructor
- functions may not take more than two arguments, but function
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/023c8ccc9fc7f11e.
Report an issue: GitHub.