{"record":{"id":"974049ef2756564b","repo":"java-native-access/jna","slug":"type-is-not-derived-from-com-sun-jna-callback","errorCode":null,"errorMessage":"<type> is not derived from com.sun.jna.Callback","messagePattern":"<type> is not derived from com\\.sun\\.jna\\.Callback","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/CallbackReference.java","lineNumber":372,"sourceCode":"    }\n\n    private static Method checkMethod(Method m) {\n        if (m.getParameterTypes().length > Function.MAX_NARGS) {\n            String msg = \"Method signature exceeds the maximum \"\n                + \"parameter count: \" + m;\n            throw new UnsupportedOperationException(msg);\n        }\n        return m;\n    }\n\n    /*\n     * Find the first instance of an interface which implements the Callback\n     * interface or an interface derived from Callback, which defines an\n     * appropriate callback method.\n     */\n    static Class<?> findCallbackClass(Class<?> type) {\n        if (!Callback.class.isAssignableFrom(type)) {\n            throw new IllegalArgumentException(type.getName() + \" is not derived from com.sun.jna.Callback\");\n        }\n        if (type.isInterface()) {\n            return type;\n        }\n        Class<?>[] ifaces = type.getInterfaces();\n        for (int i=0;i < ifaces.length;i++) {\n            if (Callback.class.isAssignableFrom(ifaces[i])) {\n                try {\n                    // Make sure it's got a recognizable callback method\n                    getCallbackMethod(ifaces[i]);\n                    return ifaces[i];\n                }\n                catch(IllegalArgumentException e) {\n                    break;\n                }\n            }\n        }\n        if (Callback.class.isAssignableFrom(type.getSuperclass())) {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/CallbackReference.java#L354-L390","documentation":"IllegalArgumentException thrown by CallbackReference.findCallbackClass when the supplied Class does not implement/extend com.sun.jna.Callback. JNA can only create native function pointers for types derived from its Callback marker interface, so passing any other type is rejected before proxy generation. This is called from getCallbackMethod and recursively while searching a class's interfaces for the Callback-derived interface.","triggerScenarios":"Passing a non-callback type where a Callback is expected: Native.getCallback on a plain interface; using a lambda-typed or Runnable-like interface not extending Callback; a structure field or Library method whose callback type lost its 'extends Callback' clause; recursion hitting an interface that doesn't derive from Callback.","commonSituations":"Typos/omissions in hand-written callback interfaces (interface MyCb { void invoke(); } without 'extends Callback'); refactoring that accidentally removed the Callback supertype; passing java.lang.Runnable/Comparable to APIs expecting a Callback.","solutions":["Declare the type as 'interface X extends com.sun.jna.Callback' and pass that type to the API.","If using a class instance, ensure its class implements a Callback-derived interface and pass the interface Class, not the concrete class.","Check imports — don't accidentally implement a different library's 'Callback' interface; reference com.sun.jna.Callback explicitly."],"exampleFix":"// before\npublic interface MyCb { void invoke(int code); }  // not a Callback\nNative.getCallback(MyCb.class, ptr); // IllegalArgumentException\n// after\npublic interface MyCb extends Callback { void invoke(int code); }\nNative.getCallback(MyCb.class, ptr);","handlingStrategy":"type-guard","validationCode":"static void requireCallbackType(Class<?> t) {\n    if (!Callback.class.isAssignableFrom(t))\n        throw new IllegalArgumentException(t.getName() + \" must extend com.sun.jna.Callback\");\n}","typeGuard":"static boolean isCallbackType(Class<?> t) {\n    return Callback.class.isAssignableFrom(t);\n}","tryCatchPattern":"try { useAsCallback(type); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"is not derived from\")) { /* fix interface declaration */ } throw e; }","preventionTips":["Every callback interface must 'extends Callback'.","Import com.sun.jna.Callback explicitly to avoid name collisions.","After refactors, re-verify the Callback supertype still exists.","Add compile-time tests asserting Callback.class.isAssignableFrom(MyCb.class)."],"tags":["jna","callback","type-mismatch","interface"],"backgroundTag":"type-mismatch","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}