{"record":{"id":"023c8ccc9fc7f11e","repo":"apache/pulsar","slug":"user-class-must-have-a-no-arg-constructor-023c8c","errorCode":null,"errorMessage":"User class must have a no-arg constructor","messagePattern":"User class must have a no-arg constructor","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java","lineNumber":152,"sourceCode":"            theCls = Class.forName(windowConfig.getTimestampExtractorClassName(),\n                    true, Thread.currentThread().getContextClassLoader());\n        } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {\n            throw new RuntimeException(\n                    String.format(\"Timestamp extractor class %s must be in class path\",\n                            windowConfig.getTimestampExtractorClassName()), cnfe);\n        }\n\n        Object result;\n        try {\n            Constructor<?> constructor = theCls.getDeclaredConstructor();\n            constructor.setAccessible(true);\n            result = constructor.newInstance();\n        } catch (InstantiationException ie) {\n            throw new RuntimeException(\"User class must be concrete\", ie);\n        } catch (NoSuchMethodException e) {\n            throw new RuntimeException(\"User class doesn't have such method\", e);\n        } catch (IllegalAccessException e) {\n            throw new RuntimeException(\"User class must have a no-arg constructor\", e);\n        } catch (InvocationTargetException e) {\n            throw new RuntimeException(\"User class constructor throws exception\", e);\n        }\n        Class<?>[] timestampExtractorTypeArgs = TypeResolver.resolveRawArguments(\n                TimestampExtractor.class, result.getClass());\n        Class<?>[] typeArgs = TypeResolver.resolveRawArguments(Function.class, this.getClass());\n        if (!typeArgs[0].equals(timestampExtractorTypeArgs[0])) {\n            throw new RuntimeException(\n                    \"Inconsistent types found between function input type and timestamp extractor type: \"\n                            + \" function type = \" + typeArgs[0] + \", timestamp extractor type = \"\n                            + timestampExtractorTypeArgs[0]);\n        }\n        return (TimestampExtractor<T>) result;\n    }\n\n    private TriggerPolicy<Record<T>, ?> getTriggerPolicy(WindowConfig windowConfig, WindowManager<Record<T>> manager,\n                                                         EvictionPolicy<Record<T>, ?> evictionPolicy, Context context) {\n        if (windowConfig.getSlidingIntervalCount() != null) {","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java#L134-L170","documentation":"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.","triggerScenarios":"Constructor is private/package-private and security manager or module restrictions block setAccessible; getDeclaredConstructor finds the constructor but newInstance cannot invoke it.","commonSituations":"Extractors written with private singletons; Java module (JPMS) boundaries blocking reflective access; class defined in a package the function instance cannot open reflectively.","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"],"exampleFix":"// before\npublic class MyExtractor implements TimestampExtractor<String> {\n    private MyExtractor() { }\n}\n// after\npublic class MyExtractor implements TimestampExtractor<String> {\n    public MyExtractor() { }\n}","handlingStrategy":"validation","validationCode":"Constructor<?> ctor = Class.forName(className).getDeclaredConstructor();\nif (!Modifier.isPublic(ctor.getModifiers())) {\n    throw new IllegalStateException(\"extractor no-arg constructor must be public: \" + className);\n}\nctor.setAccessible(true); ctor.newInstance(); // verify instantiability","typeGuard":null,"tryCatchPattern":"try {\n    executor.initialize();\n} catch (RuntimeException e) {\n    if (\"User class must have a no-arg constructor\".equals(e.getMessage())) {\n        throw new IllegalStateException(\"make the extractor constructor public and top-level\", e);\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["pulsar-functions","windowing","reflection","access-modifier"],"backgroundTag":"class-instantiation-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}