java-native-access/jna · error
JNA: extract_value: %s
Error message
JNA: extract_value: %s
What it means
In the native value-extraction routine, JNA converts a Java object argument to its native representation. When the Java type's native size is unknown the routine cannot convert it, prints this message with a detail string ('Can't convert type to native, native size N'), zeroes the output buffer, and throws a Java Lang/Error (throwByName) that the caller receives on the Java side.
Source
Thrown at native/dispatch.c:1638
}
else if ((*env)->IsInstanceOf(env, value, classStructure)) {
void* ptr = getStructureAddress(env, value);
memcpy(buffer, ptr, size);
}
else if ((*env)->IsInstanceOf(env, value, classPointer)) {
*(void **)buffer = getNativeAddress(env, value);
}
else if ((*env)->IsInstanceOf(env, value, classString)) {
*(void **)buffer = newCStringEncoding(env, (jstring)value, encoding);
}
else if ((*env)->IsInstanceOf(env, value, classWString)) {
jstring s = (*env)->CallObjectMethod(env, value, MID_Object_toString);
*(void **)buffer = newWideCString(env, s);
}
else {
char msg[MSG_SIZE];
snprintf(msg, sizeof(msg), "Can't convert type to native, native size %d\n", (int)size);
fprintf(stderr, "JNA: extract_value: %s", msg);
memset(buffer, 0, size);
throwByName(env, EError, msg);
}
}
/** Construct a new Java object from a native value. */
jobject
new_object(JNIEnv* env, char jtype, void* valuep, jboolean promote, const char* encoding) {
switch(jtype) {
case 's':
return newJavaPointer(env, valuep);
case 'c':
return newJavaString(env, *(void**)valuep, encoding);
case 'w':
return newJavaString(env, *(void **)valuep, NULL);
case '*':
return newJavaPointer(env, *(void**)valuep);
case 'J':View on GitHub (pinned to d036ad9781)
Solutions
- Read the thrown Java Error's detail message ('Can't convert type to native, native size N') to find the offending argument type and native size.
- Add a proper JNA mapping for the type: implement com.sun.jna.Callback, extend Structure, use IntegerType/Pointer, or register a TypeMapper/TypeConverter.
- Fix the native signature declaration so the parameter type matches the C prototype (e.g. use Pointer or Memory instead of an arbitrary object).
- Upgrade/downgrade JNA if the type used to map in a prior version; check the release notes for mapping changes.
Example fix
// before: unmapped custom type as structure field
class Config { String name; }
class NativeConf extends Structure { public Config conf; }
// after: map via supported types
class NativeConf extends Structure {
public byte[] conf; // or extend Structure / use TypeMapper
protected List<String> getFieldOrder() { return Collections.singletonList("conf"); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before passing an object to native, ensure JNA can map it:
if (!(arg instanceof Integer || arg instanceof Long || arg instanceof String
|| arg instanceof Pointer || arg instanceof Structure || arg instanceof Callback)) {
throw new IllegalArgumentException("Type not natively mappable: " + arg.getClass());
} Type guard
static boolean isNativelyMappable(Object o) {
return o == null || o instanceof Integer || o instanceof Long || o instanceof Short
|| o instanceof Byte || o instanceof Character || o instanceof Float || o instanceof Double
|| o instanceof Boolean || o instanceof String || o instanceof Pointer
|| o instanceof Structure || o instanceof Callback;
} Try / catch
try {
nativeLib.call(arg);
} catch (java.lang.Error e) { // JNA throws by name (Error family) from extract_value
if (String.valueOf(e.getMessage()).contains("Can't convert type to native")) {
// fix mapping: wrap arg in Pointer/Structure or register a TypeConverter
} else {
throw e;
}
} Prevention
- Use only JNA-mappable types (primitives, String, Pointer, Structure, Callback, Buffer) in native signatures.
- Register a TypeMapper for custom domain objects instead of passing them raw.
- Keep native signature declarations synchronized with the C headers.
When it happens
Trigger: Passing a Java object as a native argument (or inside a Structure/callback argument) whose mapped native size JNA cannot determine — e.g. an unmapped custom object type, a wrong @Structure.FieldOrder type, or an argument type not covered by the ToNativeContext mapping.
Common situations: Declaring a Structure field or Library method parameter as a type JNA does not know how to map (custom class without a TypeMapper/Converter); version changes where an argument was Object-typed; typos in native signatures where a primitive got boxed incorrectly.
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
- Invalid Structure field in " + getClass() + ", field name '"
- JNA: Unhandled result conversion: %d
- JNA: could not detach thread after callback init
- JNA: Can't attach native thread to VM for closure handler
- JNA: Out of memory: Can't allocate local frame
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/2985b5fe3c68e75c.
Report an issue: GitHub.