apache/pulsar · error · RuntimeException
(wraps reflective instantiation failure for interceptor)
Error message
(wraps reflective instantiation failure for interceptor)
What it means
BrokerEntryMetadataUtils.loadInterceptors loads and reflectively instantiates generic interceptor classes by name. Any InstantiationException, IllegalAccessException, InvocationTargetException, or NoSuchMethodException during construction is logged and rethrown as RuntimeException.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/intercept/BrokerEntryMetadataUtils.java:81
}
public static <T> Set<T> loadInterceptors(
Set<String> interceptorNames, ClassLoader classLoader) {
Set<T> interceptors = new LinkedHashSet<>();
if (interceptorNames != null && interceptorNames.size() > 0) {
for (String interceptorName : interceptorNames) {
try {
@SuppressWarnings("unchecked") // class is loaded by name and expected to match type T
Class<T> clz = (Class<T>) ClassLoaderUtils
.loadClass(interceptorName, classLoader);
try {
interceptors.add(clz.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException
| InvocationTargetException | NoSuchMethodException e) {
log.error()
.attr("interceptorName", interceptorName)
.exception(e)
.log("Create new instance failed.");
throw new RuntimeException(e);
}
} catch (ClassNotFoundException e) {
log.error()
.attr("interceptorName", interceptorName)
.exception(e)
.log("Load class failed.");
throw new RuntimeException(e);
}
}
}
return interceptors;
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Add a public no-arg constructor to the interceptor and make the class concrete/public
- Fix any exception thrown inside the interceptor's constructor (check the wrapped InvocationTargetException cause)
- Ensure the class and constructor are public so reflection can access them
Example fix
// before
public class MyInterceptor implements BrokerEntryMetadataInterceptor {
private MyInterceptor() {}
}
// after
public class MyInterceptor implements BrokerEntryMetadataInterceptor {
public MyInterceptor() {}
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(interceptorName);
if (Modifier.isAbstract(c.getModifiers())) {
throw new IllegalArgumentException("Interceptor cannot be abstract: " + interceptorName);
}
Constructor<?> ctor = c.getDeclaredConstructor();
ctor.setAccessible(true);
ctor.newInstance(); // dry-run: surfaces InvocationTargetException early Try / catch
try {
interceptors = BrokerEntryMetadataUtils.loadInterceptors(names, cl, Interceptor.class);
} catch (RuntimeException e) {
Throwable cause = e.getCause();
log.error("Interceptor {} could not be instantiated: {}", names, cause == null ? e : cause.getMessage());
throw e;
} Prevention
- Ensure interceptor constructors are public, no-arg, and side-effect free
- Unit-test instantiation of each configured interceptor class
- Avoid heavy/throwing initialization in constructors
When it happens
Trigger: Configured interceptor class is abstract, lacks an accessible no-arg constructor, or its constructor throws during execution, when calling loadInterceptors with an interceptor name.
Common situations: Custom interceptor implementations that define only parameterized constructors, constructors that throw in initialization code, classes not designed to be reflectively instantiated.
Related errors
- (wraps reflective instantiation failure for BrokerEntryMetad
- (wraps ClassNotFoundException for interceptor)
- 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/57701a4aa177767a.
Report an issue: GitHub.