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

  1. 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.
  2. Add a proper JNA mapping for the type: implement com.sun.jna.Callback, extend Structure, use IntegerType/Pointer, or register a TypeMapper/TypeConverter.
  3. Fix the native signature declaration so the parameter type matches the C prototype (e.g. use Pointer or Memory instead of an arbitrary object).
  4. 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

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


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/2985b5fe3c68e75c. Report an issue: GitHub.