java-native-access/jna · error · IllegalArgumentException

Reading \"" + type + "\" from memory is not supported

Error message

Reading \"" + type + "\" from memory is not supported

What it means

Pointer.getValue() reached a Java type it cannot reconstruct from native memory. JNA only knows how to map a fixed set of types (primitives, wrappers, String, Structure, Callback, Pointer, NativeMapped); anything else is rejected with IllegalArgumentException rather than silently producing garbage.

Source

Thrown at src/com/sun/jna/Pointer.java:452

            if (nm != null) {
                Object value = getValue(offset, nm.nativeType(), null);
                result = nm.fromNative(value, new FromNativeContext(type));
                if (nm.equals(result)) {
                    result = nm;
                }
            } else {
                NativeMappedConverter tc = NativeMappedConverter.getInstance(type);
                Object value = getValue(offset, tc.nativeType(), null);
                result = tc.fromNative(value, new FromNativeContext(type));
            }
        } else if (type.isArray()) {
            result = currentValue;
            if (result == null) {
                throw new IllegalStateException("Need an initialized array");
            }
            readArray(offset, result, type.getComponentType());
        } else {
            throw new IllegalArgumentException("Reading \"" + type + "\" from memory is not supported");
        }
        return result;
    }

    /** Read memory starting at offset into the array with element type cls. */
    private void readArray(long offset, Object o, Class<?> cls) {
        int length = 0;
        length = Array.getLength(o);
        Object result = o;

        if (cls == byte.class) {
            read(offset, (byte[])result, 0, length);
        }
        else if (cls == short.class) {
            read(offset, (short[])result, 0, length);
        }
        else if (cls == char.class) {
            read(offset, (char[])result, 0, length);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Use a type JNA supports natively: primitives, Byte/Short/Integer/Long/Float/Double/Character/Boolean, String, Pointer, Structure, Callback, or WString.
  2. If the type is a custom mapping, implement com.sun.jna.NativeMapped (with fromNative/toNative/nativeType) so getValue can convert it.
  3. For arrays, call pointer.get*Array methods or getValue with the array instance and a supported component type instead.
  4. Inspect the stack trace's type value to see which unsupported class was requested and fix the caller's expected type.

Example fix

// before
List result = (List) pointer.getValue(0, List.class, null);
// after
// map to a supported type or implement NativeMapped on the custom class
class MyMapped implements NativeMapped { /* fromNative/toNative/nativeType */ }
MyMapped result = (MyMapped) pointer.getValue(0, MyMapped.class, null);
Defensive patterns

Strategy: type-guard

Validate before calling

private static boolean isSupportedValueType(Class<?> t) {
    return t.isPrimitive() || Number.class.isAssignableFrom(t) || t == Boolean.class
        || t == Character.class || t == String.class || t == WString.class
        || Pointer.class.isAssignableFrom(t) || Structure.class.isAssignableFrom(t)
        || Callback.class.isAssignableFrom(t) || NativeMapped.class.isAssignableFrom(t);
}
// call: if (!isSupportedValueType(type)) throw new IllegalArgumentException(type + " not mappable");

Type guard

static boolean isJnaMappable(Class<?> t) {
    return t.isPrimitive() || Number.class.isAssignableFrom(t) || t == String.class
        || t == Boolean.class || t == Character.class || Pointer.class.isAssignableFrom(t)
        || Structure.class.isAssignableFrom(t) || Callback.class.isAssignableFrom(t)
        || NativeMapped.class.isAssignableFrom(t);
}

Try / catch

try {
    Object v = pointer.getValue(offset, type, null);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Reading")) {
        // fall back to a supported mapping or NativeMapped conversion
    } else throw e;
}

Prevention

When it happens

Trigger: Calling pointer.getValue(offset, type, ...) where `type` is neither a supported primitive/wrapper, String, Structure, Callback, Pointer, nor a NativeMapped-implementing class — e.g. getValue(0, java.util.List.class, null) or an unmapped custom POJO.

Common situations: Passing a generic Java collection (List, Map) or an arbitrary domain object as the expected return type of a native call; accidentally using the Java field's declared type (e.g. an interface or enum) instead of the mapped native type in a Structure/Function return.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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