{"record":{"id":"12c43a6a12f35369","repo":"apache/pulsar","slug":"user-class-must-be-in-class-path","errorCode":null,"errorMessage":"User class must be in class path","messagePattern":"User class must be in class path","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java","lineNumber":72,"sourceCode":"    }\n\n    /**\n     * Create an instance of <code>userClassName</code> using provided <code>classLoader</code>.\n     * This instance should implement the provided interface <code>xface</code>.\n     *\n     * @param userClassName user class name\n     * @param xface the interface that the reflected instance should implement\n     * @param classLoader class loader to load the class.\n     * @return the instance\n     */\n    public static <T> T createInstance(String userClassName,\n                                       Class<T> xface,\n                                       ClassLoader classLoader) {\n        Class<?> theCls;\n        try {\n            theCls = Class.forName(userClassName, true, classLoader);\n        } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {\n            throw new RuntimeException(\"User class must be in class path\", cnfe);\n        }\n        if (!xface.isAssignableFrom(theCls)) {\n            throw new RuntimeException(userClassName + \" does not implement \" + xface.getName());\n        }\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);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java#L54-L90","documentation":"Reflections.createInstance(String, Class<T>, ClassLoader) loads a user-supplied class name and verifies it implements the requested interface. If Class.forName cannot load the class (ClassNotFoundException or NoClassDefFoundError), it wraps the failure in this RuntimeException. It means the configured class name is wrong or its dependencies are missing from the given classloader.","triggerScenarios":"Passing a class name string that is misspelled, uses the wrong package, or whose class file is absent from `classLoader`; the class exists but a referenced type in its signature is missing (NoClassDefFoundError).","commonSituations":"Typo in configuration like `interceptorName` or `entryFilterClassName`; fat-jar/plugin directory not on the NarClassLoader; class moved/renamed after a Pulsar upgrade.","solutions":["Check the class name string for typos and correct package (fully qualified name)","Confirm the jar/plugin bundle is actually available to the given classLoader","Inspect the wrapped `cnfe` cause — NoClassDefFoundError usually names a missing dependency class","Rebuild/redeploy the plugin after upgrades so the packaged class matches the new API"],"exampleFix":"// before\nReflections.createInstance(\"org.example.MyFilter\", Filter.class, loader);\n// after (corrected FQN and jar deployed)\nReflections.createInstance(\"org.example.plugins.MyEntryFilter\", Filter.class, loader);","handlingStrategy":"try-catch","validationCode":"// pre-check that the class loads before calling createInstance\ntry {\n    Class.forName(className, true, classLoader);\n} catch (ClassNotFoundException | NoClassDefFoundError e) {\n    throw new IllegalArgumentException(\"Class not on classpath: \" + className, e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    T obj = Reflections.createInstance(className, XFace.class, classLoader);\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"User class must be in class path\")) {\n        throw new IllegalArgumentException(\"Check configured class name and plugin jar: \" + className, e);\n    }\n    throw e;\n}","preventionTips":["Store fully qualified class names in config, verified by a startup self-check","Verify the plugin/Nar jar is deployed and loadable by the exact classloader you pass","Re-check class names after any dependency or Pulsar version upgrade"],"tags":["reflection","classpath","configuration"],"backgroundTag":"classnotfound","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}