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

  1. Add @Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})) to the interceptor class.
  2. Declare the annotation directly on the registered class, not only on a parent — @Intercepts is not @Inherited.
  3. 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

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


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/19a5e62e8fc7a9c4. Report an issue: GitHub.