pinpoint-apm/pinpoint · error · RuntimeException

duplicated method exist. methodName:${methodName}

Error message

duplicated method exist. methodName:${methodName}

What it means

RuntimeException("duplicated method exist. methodName:...") thrown by InterceptorDefinitionFactory.findMethodByName when more than one declared method shares the target name (before or after). Pinpoint requires a single unambiguous before()/after() per interceptor class.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/interceptor/InterceptorDefinitionFactory.java:145

        return new TypeHandler(interceptorClazz, interceptorType, before, beforeParamList, after, afterParamList);
    }


    private Method findMethodByName(Method[] declaredMethods, String methodName) {
        Method findMethod = null;
        int count = 0;
        for (Method method : declaredMethods) {
            if (method.getName().equals(methodName)) {
                count++;
                findMethod = method;
            }
        }
        if (findMethod == null) {
            throw new RuntimeException(methodName + " not found");
        }
        if (count > 1 ) {
            throw new RuntimeException("duplicated method exist. methodName:" + methodName);
        }
        return findMethod;
    }


    private class TypeHandler {
        private final Class<? extends Interceptor> interceptorClazz;
        private final InterceptorType interceptorType;
        private final String before;
        private final Class<?>[] beforeParamList;
        private final String after;
        private final Class<?>[] afterParamList;

        public TypeHandler(Class<? extends Interceptor> interceptorClazz, InterceptorType interceptorType, String before, final Class<?>[] beforeParamList, final String after, final Class<?>[] afterParamList) {
            this.interceptorClazz = Objects.requireNonNull(interceptorClazz, "interceptorClazz");
            this.interceptorType = Objects.requireNonNull(interceptorType, "interceptorType");
            this.before = Objects.requireNonNull(before, "before");
            this.beforeParamList = Objects.requireNonNull(beforeParamList, "beforeParamList");

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Keep exactly one before() and one after() method; remove any overloads.
  2. Move overload dispatch logic inside the single before/after body using argument inspection.
  3. If inheritance causes the duplicate, flatten the class so only one declaration exists in the concrete interceptor.

Example fix

// before
public void before(Object t, Object[] a) { }
public void before(Object t) { } // duplicate
// after
public void before(Object t, Object[] a) { /* handle both cases */ }
Defensive patterns

Strategy: validation

Validate before calling

Map<String, Long> counts = Arrays.stream(clazz.getDeclaredMethods())
    .collect(Collectors.groupingBy(Method::getName, Collectors.counting()));
if (counts.getOrDefault("before", 0L) > 1 || counts.getOrDefault("after", 0L) > 1) {
    throw new IllegalArgumentException(clazz + " has duplicated before/after overloads");
}

Try / catch

try { factory.createInterceptorDefinition(clazz); } catch (RuntimeException e) { if (e.getMessage().startsWith("duplicated method exist")) { /* remove overloads */ } throw e; }

Prevention

When it happens

Trigger: The interceptor class declares two or more overloads named before or after (e.g. before(Object) and before(Object, Object[])) - getDeclaredMethods() returns both, count > 1, and the factory aborts.

Common situations: Adding an overload of before/after for convenience, or extending a class that declares its own before/after in addition to the subclass's (declared methods of the concrete class plus bridge methods).

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/7c60b5ae478fc3e1. Report an issue: GitHub.