{"record":{"id":"75750594a1c4a447","repo":"java-native-access/jna","slug":"reading-type-from-memory-is-not-supported","errorCode":null,"errorMessage":"Reading \\\"\" + type + \"\\\" from memory is not supported","messagePattern":"Reading \\\\\"\" \\+ type \\+ \"\\\\\" from memory is not supported","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Pointer.java","lineNumber":452,"sourceCode":"            if (nm != null) {\n                Object value = getValue(offset, nm.nativeType(), null);\n                result = nm.fromNative(value, new FromNativeContext(type));\n                if (nm.equals(result)) {\n                    result = nm;\n                }\n            } else {\n                NativeMappedConverter tc = NativeMappedConverter.getInstance(type);\n                Object value = getValue(offset, tc.nativeType(), null);\n                result = tc.fromNative(value, new FromNativeContext(type));\n            }\n        } else if (type.isArray()) {\n            result = currentValue;\n            if (result == null) {\n                throw new IllegalStateException(\"Need an initialized array\");\n            }\n            readArray(offset, result, type.getComponentType());\n        } else {\n            throw new IllegalArgumentException(\"Reading \\\"\" + type + \"\\\" from memory is not supported\");\n        }\n        return result;\n    }\n\n    /** Read memory starting at offset into the array with element type cls. */\n    private void readArray(long offset, Object o, Class<?> cls) {\n        int length = 0;\n        length = Array.getLength(o);\n        Object result = o;\n\n        if (cls == byte.class) {\n            read(offset, (byte[])result, 0, length);\n        }\n        else if (cls == short.class) {\n            read(offset, (short[])result, 0, length);\n        }\n        else if (cls == char.class) {\n            read(offset, (char[])result, 0, length);","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Pointer.java#L434-L470","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use a type JNA supports natively: primitives, Byte/Short/Integer/Long/Float/Double/Character/Boolean, String, Pointer, Structure, Callback, or WString.","If the type is a custom mapping, implement com.sun.jna.NativeMapped (with fromNative/toNative/nativeType) so getValue can convert it.","For arrays, call pointer.get*Array methods or getValue with the array instance and a supported component type instead.","Inspect the stack trace's type value to see which unsupported class was requested and fix the caller's expected type."],"exampleFix":"// before\nList result = (List) pointer.getValue(0, List.class, null);\n// after\n// map to a supported type or implement NativeMapped on the custom class\nclass MyMapped implements NativeMapped { /* fromNative/toNative/nativeType */ }\nMyMapped result = (MyMapped) pointer.getValue(0, MyMapped.class, null);","handlingStrategy":"type-guard","validationCode":"private static boolean isSupportedValueType(Class<?> t) {\n    return t.isPrimitive() || Number.class.isAssignableFrom(t) || t == Boolean.class\n        || t == Character.class || t == String.class || t == WString.class\n        || Pointer.class.isAssignableFrom(t) || Structure.class.isAssignableFrom(t)\n        || Callback.class.isAssignableFrom(t) || NativeMapped.class.isAssignableFrom(t);\n}\n// call: if (!isSupportedValueType(type)) throw new IllegalArgumentException(type + \" not mappable\");","typeGuard":"static boolean isJnaMappable(Class<?> t) {\n    return t.isPrimitive() || Number.class.isAssignableFrom(t) || t == String.class\n        || t == Boolean.class || t == Character.class || Pointer.class.isAssignableFrom(t)\n        || Structure.class.isAssignableFrom(t) || Callback.class.isAssignableFrom(t)\n        || NativeMapped.class.isAssignableFrom(t);\n}","tryCatchPattern":"try {\n    Object v = pointer.getValue(offset, type, null);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Reading\")) {\n        // fall back to a supported mapping or NativeMapped conversion\n    } else throw e;\n}","preventionTips":["Restrict Structure fields and getValue types to JNA-supported mappings.","Implement NativeMapped for any custom type crossing the native boundary.","Never request List/Map/POJO types directly from native memory.","Review JNA's supported-type table (Function/Pointer javadoc) when adding new mapped fields."],"tags":["java","jna","native-memory","type-mapping"],"backgroundTag":"unsupported-operation","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}