pinpoint-apm/pinpoint · error · PinpointException
transformCallbackClass must be static inner class. class:
Error message
transformCallbackClass must be static inner class. class:
What it means
TransformCallbackChecker.validate enforces that a TransformCallback supplied to TransformTemplate is either a top-level class or, if it is an inner (nested) class, that it is declared static. A non-static inner class cannot be instantiated by the instrumentation layer without an enclosing instance, so a PinpointException is thrown naming the offending class.
Source
Thrown at agent-module/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/instrument/transformer/TransformCallbackChecker.java:45
public final class TransformCallbackChecker {
private TransformCallbackChecker() {
}
public static void validate(Class<? extends TransformCallback> transformCallbackClass) {
validate(transformCallbackClass, null);
}
public static void validate(Class<? extends TransformCallback> transformCallbackClass, Class<?>[] parameterTypes) {
Objects.requireNonNull(transformCallbackClass, "transformCallbackClass");
// check inner class
final Class<?> enclosingClass = transformCallbackClass.getEnclosingClass();
if (enclosingClass != null) {
// inner class state
// check static class
int modifiers = transformCallbackClass.getModifiers();
if (!Modifier.isStatic(modifiers)) {
throw new PinpointException("transformCallbackClass must be static inner class. class:" + transformCallbackClass.getName());
}
}
// final Method enclosingMethod = transformCallbackClass.getEnclosingMethod();
// if (enclosingMethod != null) {
// throw new PinpointException("Local Inner class not support " + transformCallbackClass.getName());
// }
try {
// check default constructor
transformCallbackClass.getConstructor(parameterTypes);
} catch (NoSuchMethodException e) {
throw new PinpointException("constructor not found " + transformCallbackClass.getName(), e);
}
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Add the static modifier to the nested TransformCallback class
- Move the callback to a top-level class instead of nesting it
- If a local/anonymous class is used, promote it to a named static nested or top-level class
Example fix
// before
class Plugin {
class MyCallback implements TransformCallback { ... } // non-static inner
}
// after
class Plugin {
static class MyCallback implements TransformCallback { ... }
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> cb = MyCallback.class;
if (cb.getEnclosingClass() != null && !Modifier.isStatic(cb.getModifiers())) {
throw new IllegalStateException("TransformCallback inner class must be static: " + cb.getName());
} Type guard
boolean isValidCallbackClass(Class<?> c) {
return c.getEnclosingClass() == null || Modifier.isStatic(c.getModifiers());
} Try / catch
try {
transformer.transform(name, cb, null, null);
} catch (PinpointException e) {
if (e.getMessage().startsWith("transformCallbackClass must be static inner class")) {
logger.error("declare the callback as a static nested or top-level class", e);
} else { throw e; }
} Prevention
- Always declare TransformCallback implementations as static nested or top-level classes
- Never use non-static inner, local, or anonymous classes as callbacks
- Add a unit test asserting the callback class passes TransformCallbackChecker.validate
When it happens
Trigger: Passing a non-static inner class (an inner class that implicitly holds a reference to its enclosing instance) as the transformCallbackClass argument to TransformTemplate.transform().
Common situations: Defining the TransformCallback as an inner class of a plugin class without the static keyword; refactoring a top-level callback into a nested one and losing static; Kotlin/Java nesting mistakes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- null parameterType not supported
- Invalid time unit provided.
- unsupported type:
- constructor not found
- not found
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/db059ca3abeb6a66.
Report an issue: GitHub.