mybatis/mybatis-3 · error · PluginException
No @Intercepts annotation was found in interceptor {}
Error message
No @Intercepts annotation was found in interceptor {} What it means
Plugin.getSignatureMap() requires every Interceptor to carry the @Intercepts annotation; it is the only source of @Signature entries telling MyBatis which target interface methods to proxy. Without it the plugin cannot be wired at all.
Source
Thrown at src/main/java/org/apache/ibatis/plugin/Plugin.java:70
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
} catch (Exception e) {
throw ExceptionUtil.unwrapThrowable(e);
}
}
private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
// issue #251
if (interceptsAnnotation == null) {
throw new PluginException(
"No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());
}
Signature[] sigs = interceptsAnnotation.value();
Map<Class<?>, Set<Method>> signatureMap = new HashMap<>();
for (Signature sig : sigs) {
Set<Method> methods = signatureMap.computeIfAbsent(sig.type(), k -> new HashSet<>());
try {
Method method = sig.type().getMethod(sig.method(), sig.args());
methods.add(method);
} catch (NoSuchMethodException e) {
throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e,
e);
}
}
return signatureMap;
}
private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) {View on GitHub (pinned to 008069adb1)
Solutions
- Add @Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})) to the interceptor class.
- Declare the annotation directly on the registered class, not only on a parent — @Intercepts is not @Inherited.
- Verify the class actually implements org.apache.ibatis.plugin.Interceptor.
Example fix
// before
public class SqlLogger implements Interceptor { ... }
// after
@Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}))
public class SqlLogger implements Interceptor { ... } Defensive patterns
Strategy: validation
Validate before calling
if (interceptor.getClass().getAnnotation(Intercepts.class) == null) {
throw new IllegalStateException(interceptor.getClass().getName() + " must be annotated with @Intercepts");
} Prevention
- Put @Intercepts directly on every registered interceptor class (it is not inherited).
- Add a startup assertion/scan that all Interceptor beans carry @Intercepts.
When it happens
Trigger: Registering an Interceptor implementation (via <plugins> in XML, Configuration.addInterceptor, or auto-detection) whose class lacks @Intercepts.
Common situations: Copy-pasted interceptor with the annotation accidentally removed; interceptor subclassing an annotated base but the subclass is registered while the annotation lives on the base (getAnnotation does not inherit @Intercepts unless @Inherited); migrating to a different plugin mechanism.
Related errors
- Method '{}' is not supported as a plugin target.
- Could not find method on {} named {}. Cause: {}
- Should be specified either value() or name() attribute in th
- Cannot use both value() and name() attribute in the @CacheNa
- If there is no type discriminator, then the NamedResultMap a
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/19a5e62e8fc7a9c4.
Report an issue: GitHub.