java-native-access/jna · error · IllegalArgumentException
<type> is not derived from com.sun.jna.Callback
Error message
<type> is not derived from com.sun.jna.Callback
What it means
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.
Source
Thrown at src/com/sun/jna/CallbackReference.java:372
}
private static Method checkMethod(Method m) {
if (m.getParameterTypes().length > Function.MAX_NARGS) {
String msg = "Method signature exceeds the maximum "
+ "parameter count: " + m;
throw new UnsupportedOperationException(msg);
}
return m;
}
/*
* Find the first instance of an interface which implements the Callback
* interface or an interface derived from Callback, which defines an
* appropriate callback method.
*/
static Class<?> findCallbackClass(Class<?> type) {
if (!Callback.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(type.getName() + " is not derived from com.sun.jna.Callback");
}
if (type.isInterface()) {
return type;
}
Class<?>[] ifaces = type.getInterfaces();
for (int i=0;i < ifaces.length;i++) {
if (Callback.class.isAssignableFrom(ifaces[i])) {
try {
// Make sure it's got a recognizable callback method
getCallbackMethod(ifaces[i]);
return ifaces[i];
}
catch(IllegalArgumentException e) {
break;
}
}
}
if (Callback.class.isAssignableFrom(type.getSuperclass())) {View on GitHub (pinned to d036ad9781)
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.
Example fix
// before
public interface MyCb { void invoke(int code); } // not a Callback
Native.getCallback(MyCb.class, ptr); // IllegalArgumentException
// after
public interface MyCb extends Callback { void invoke(int code); }
Native.getCallback(MyCb.class, ptr); Defensive patterns
Strategy: type-guard
Validate before calling
static void requireCallbackType(Class<?> t) {
if (!Callback.class.isAssignableFrom(t))
throw new IllegalArgumentException(t.getName() + " must extend com.sun.jna.Callback");
} Type guard
static boolean isCallbackType(Class<?> t) {
return Callback.class.isAssignableFrom(t);
} Try / catch
try { useAsCallback(type); } catch (IllegalArgumentException e) { if (e.getMessage().contains("is not derived from")) { /* fix interface declaration */ } throw e; } Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Callback type must be an interface
- Structure Callback field '" + field.getName() + "' must be a
- Unexpected registry type + lpType.getValue() + , expected RE
- Unexpected registry type + lpType.getValue() + , expected RE
- Unexpected registry type {}, expected REG_SZ
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/974049ef2756564b.
Report an issue: GitHub.