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
- Keep exactly one before() and one after() method; remove any overloads.
- Move overload dispatch logic inside the single before/after body using argument inspection.
- 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
- No overloads of before/after in interceptor classes
- Flatten inheritance so only one declaration exists
- Add a unit test that builds every interceptor definition at startup
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
- ${methodName} not found
- ${before} method not found. ${Arrays.toString(beforeParamLis
- ${moduleFactoryClazzName} ModuleFactory initialize fail
- invocation fail, className=
- not found 'get' method, className=
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/7c60b5ae478fc3e1.
Report an issue: GitHub.