{"record":{"id":"5a37c48a113e4219","repo":"apache/pulsar","slug":"user-class-must-have-a-public-constructor","errorCode":null,"errorMessage":"User class must have a public constructor","messagePattern":"User class must have a public constructor","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java","lineNumber":94,"sourceCode":"        }\n        @SuppressWarnings(\"unchecked\") // safe: theCls is verified to be assignable to xface\n        Class<T> tCls = (Class<T>) theCls.asSubclass(xface);\n        T result;\n        try {\n            @SuppressWarnings(\"unchecked\") // safe: constructor cache is keyed by theCls which extends T\n            Constructor<T> meth = (Constructor<T>) constructorCache.get(theCls);\n            if (null == meth) {\n                meth = tCls.getDeclaredConstructor();\n                meth.setAccessible(true);\n                constructorCache.put(theCls, meth);\n            }\n            result = meth.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 must have a no-arg constructor\", e);\n        } catch (IllegalAccessException e) {\n            throw new RuntimeException(\"User class must have a public constructor\", e);\n        } catch (InvocationTargetException e) {\n            throw new RuntimeException(\"User class constructor throws exception\", e);\n        }\n        return result;\n\n    }\n\n    /**\n     * Create an instance of <code>userClassName</code> using provided <code>classLoader</code>.\n     *\n     * @param userClassName user class name\n     * @param classLoader class loader to load the class.\n     * @return the instance\n     */\n    public static Object createInstance(String userClassName,\n                                        ClassLoader classLoader) {\n        Class<?> theCls;\n        try {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java#L76-L112","documentation":"After locating the no-arg constructor, createInstance calls setAccessible(true) and newInstance(). IllegalAccessException (e.g. the class or constructor is not public, or the class is in a non-opened package) is wrapped in this RuntimeException whose message says the user class must have a public constructor.","triggerScenarios":"Configuring a package-private or private class (or non-public constructor) for reflective instantiation, so newInstance() throws IllegalAccessException even though a no-arg constructor exists.","commonSituations":"Declaring the plugin class package-private; JPMS module that does not `opens`/`exports` its package to the caller; narrowing constructor visibility during refactoring.","solutions":["Make both the class and its no-arg constructor `public`","If using JPMS, add `opens <package>;` to module-info for the calling module","Keep constructor visibility public after refactors that add constructors"],"exampleFix":"// before\nclass MyFilter implements Filter { MyFilter() { } }\n// after\npublic class MyFilter implements Filter { public MyFilter() { } }","handlingStrategy":"validation","validationCode":"// verify public accessibility before instantiation\nClass<?> cls = Class.forName(className, true, classLoader);\njava.lang.reflect.Constructor<?> c = cls.getDeclaredConstructor();\nif (!Modifier.isPublic(cls.getModifiers()) || !Modifier.isPublic(c.getModifiers())) {\n    throw new IllegalArgumentException(\"Class and no-arg constructor must be public: \" + className);\n}","typeGuard":"boolean isPubliclyInstantiable(Class<?> cls) {\n    try { return Modifier.isPublic(cls.getModifiers()) && Modifier.isPublic(cls.getDeclaredConstructor().getModifiers()); }\n    catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    T obj = Reflections.createInstance(className, XFace.class, classLoader);\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"User class must have a public constructor\")) {\n        throw new IllegalArgumentException(\"Make \" + className + \" and its constructor public\", e);\n    }\n    throw e;\n}","preventionTips":["Declare plugin classes and constructors `public`","For JPMS, add `opens <package>` in module-info for packages holding such classes","Review visibility during refactors that touch constructor modifiers"],"tags":["reflection","access-modifier","visibility"],"backgroundTag":"illegal-access-exception","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"}