apache/pulsar · error · IllegalArgumentException
Cannot find/load class
Error message
Cannot find/load class
What it means
Thrown by ClassLoaderUtils.implementsClass when loadClass cannot find or link the named class — a ClassNotFoundException or NoClassDefFoundError is caught and rethrown as an IllegalArgumentException with 'Cannot find/load class '. Note the cause is dropped, so the underlying linking error is not visible in the new exception.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/ClassLoaderUtils.java:72
Class<?> objectClass;
try {
objectClass = Class.forName(className);
} catch (ClassNotFoundException | NoClassDefFoundError e) {
if (classLoader != null) {
objectClass = classLoader.loadClass(className);
} else {
throw e;
}
}
return objectClass;
}
public static void implementsClass(String className, Class<?> klass, ClassLoader classLoader) {
Class<?> objectClass;
try {
objectClass = loadClass(className, classLoader);
} catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new IllegalArgumentException("Cannot find/load class " + className);
}
if (!klass.isAssignableFrom(objectClass)) {
throw new IllegalArgumentException(
String.format("%s does not implement %s", className, klass.getName()));
}
}
public static void closeClassLoader(ClassLoader classLoader) {
if (classLoader instanceof Closeable) {
try {
((Closeable) classLoader).close();
} catch (IOException e) {
log.error().attr("classLoader", classLoader).exception(e).log("Error closing classloader");
}
}
}
}View on GitHub (pinned to 820761864e)
Solutions
- Verify the fully-qualified class name in configuration is spelled correctly and matches the deployed jar
- Ensure the jar containing the class (and its dependencies) is deployed to the location the classLoader reads
- Check logs for the original ClassNotFoundException/NoClassDefFoundError cause, since this exception drops it
- Pass the correct ClassLoader (e.g. the plugin/nar class loader) rather than the default one
Example fix
// before
ClassLoaderUtils.implementsClass("com.acme.MyFunction", Function.class, classLoader); // jar not deployed
// after
// deploy my-function.jar to the functions directory first, then:
ClassLoader cl = new URLClassLoader(new File("functions/my-function.jar").toURI().toURL(), parentCl);
ClassLoaderUtils.implementsClass("com.acme.MyFunction", Function.class, cl); Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(className, false, classLoader);
} catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new IllegalStateException("class not loadable from given classloader: " + className, e);
} Type guard
static boolean isClassLoadable(String className, ClassLoader cl) {
try { Class.forName(className, false, cl); return true; }
catch (ClassNotFoundException | NoClassDefFoundError e) { return false; }
} Try / catch
try {
ClassLoaderUtils.implementsClass(className, Function.class, cl);
} catch (IllegalArgumentException e) {
log.error("Cannot load plugin class {} (check jar deployment/classpath)", className);
throw e;
} Prevention
- Verify the jar is deployed where the classLoader resolves it
- Log the original cause — this error message drops ClassNotFoundException/NoClassDefFoundError details
- Use the correct (plugin/nar) class loader, not the system one
- Validate plugin config class names at startup, not lazily at runtime
When it happens
Trigger: Calling implementsClass(className, klass, classLoader) where the className is misspelled, the class is missing from the given ClassLoader, the class fails static initialization (NoClassDefFoundError), or a dependency class is missing at link time.
Common situations: Plugin/nar jar not on the broker classpath; function/searchplug-in configuration pointing at a class that was renamed between versions; wrong ClassLoader passed (e.g. system loader instead of the nar loader); missing transitive dependencies causing NoClassDefFoundError at first use.
Related errors
- Error when loading topic compaction strategy:
- %s does not implement %s
- Failed to instantiate ${className}
- Exception caused while converting configuration: ${message}
- Failed to compute configuration overrides
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f5cc0c5ec4f794ce.
Report an issue: GitHub.