{"record":{"id":"db059ca3abeb6a66","repo":"pinpoint-apm/pinpoint","slug":"transformcallbackclass-must-be-static-inner-class","errorCode":null,"errorMessage":"transformCallbackClass must be static inner class. class:","messagePattern":"transformCallbackClass must be static inner class\\. class:","errorType":"exception","errorClass":"PinpointException","httpStatus":null,"severity":"error","filePath":"agent-module/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/instrument/transformer/TransformCallbackChecker.java","lineNumber":45,"sourceCode":"public final class TransformCallbackChecker {\n    private TransformCallbackChecker() {\n    }\n\n    public static void validate(Class<? extends TransformCallback> transformCallbackClass) {\n        validate(transformCallbackClass, null);\n    }\n    public static void validate(Class<? extends TransformCallback> transformCallbackClass, Class<?>[] parameterTypes) {\n        Objects.requireNonNull(transformCallbackClass, \"transformCallbackClass\");\n\n        // check inner class\n        final Class<?> enclosingClass = transformCallbackClass.getEnclosingClass();\n        if (enclosingClass != null) {\n            // inner class state\n\n            // check static class\n            int modifiers = transformCallbackClass.getModifiers();\n            if (!Modifier.isStatic(modifiers)) {\n                throw new PinpointException(\"transformCallbackClass must be static inner class. class:\" + transformCallbackClass.getName());\n            }\n        }\n//        final Method enclosingMethod = transformCallbackClass.getEnclosingMethod();\n//        if (enclosingMethod != null) {\n//            throw new PinpointException(\"Local Inner class not support \" + transformCallbackClass.getName());\n//        }\n\n        try {\n            // check default constructor\n            transformCallbackClass.getConstructor(parameterTypes);\n        } catch (NoSuchMethodException e) {\n            throw new PinpointException(\"constructor not found \" + transformCallbackClass.getName(), e);\n        }\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":61,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/instrument/transformer/TransformCallbackChecker.java#L27-L61","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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"],"exampleFix":"// before\nclass Plugin {\n    class MyCallback implements TransformCallback { ... } // non-static inner\n}\n// after\nclass Plugin {\n    static class MyCallback implements TransformCallback { ... }\n}","handlingStrategy":"validation","validationCode":"Class<?> cb = MyCallback.class;\nif (cb.getEnclosingClass() != null && !Modifier.isStatic(cb.getModifiers())) {\n    throw new IllegalStateException(\"TransformCallback inner class must be static: \" + cb.getName());\n}","typeGuard":"boolean isValidCallbackClass(Class<?> c) {\n    return c.getEnclosingClass() == null || Modifier.isStatic(c.getModifiers());\n}","tryCatchPattern":"try {\n    transformer.transform(name, cb, null, null);\n} catch (PinpointException e) {\n    if (e.getMessage().startsWith(\"transformCallbackClass must be static inner class\")) {\n        logger.error(\"declare the callback as a static nested or top-level class\", e);\n    } else { throw e; }\n}","preventionTips":["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"],"tags":["inner-class","transform-callback","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}