{"record":{"id":"9bb851093d1f7634","repo":"java-native-access/jna","slug":"type-must-derive-from-nativemapped-class","errorCode":null,"errorMessage":"Type must derive from NativeMapped.class","messagePattern":"Type must derive from NativeMapped\\.class","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/NativeMappedConverter.java","lineNumber":54,"sourceCode":"    private final Class<?> type;\n    private final Class<?> nativeType;\n    private final NativeMapped instance;\n\n    public static NativeMappedConverter getInstance(Class<?> cls) {\n        synchronized(converters) {\n            Reference<NativeMappedConverter> r = converters.get(cls);\n            NativeMappedConverter nmc = r != null ? r.get() : null;\n            if (nmc == null) {\n                nmc = new NativeMappedConverter(cls);\n                converters.put(cls, new SoftReference<>(nmc));\n            }\n            return nmc;\n        }\n    }\n\n    public NativeMappedConverter(Class<?> type) {\n        if (!NativeMapped.class.isAssignableFrom(type))\n            throw new IllegalArgumentException(\"Type must derive from \" + NativeMapped.class);\n        this.type = type;\n        this.instance = defaultValue();\n        this.nativeType = instance.nativeType();\n    }\n\n    public NativeMapped defaultValue() {\n        if (type.isEnum()) {\n            return (NativeMapped) type.getEnumConstants()[0];\n        }\n\n        return (NativeMapped) Klass.newInstance(type);\n    }\n\n    @Override\n    public Object fromNative(Object nativeValue, FromNativeContext context) {\n        return instance.fromNative(nativeValue, context);\n    }\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/NativeMappedConverter.java#L36-L72","documentation":"NativeMappedConverter's constructor throws IllegalArgumentException when the given class does not implement com.sun.jna.NativeMapped. The converter only knows how to map types that provide custom toNative/fromNative conversions via that interface.","triggerScenarios":"Registering or instantiating a type mapping (Native.setTypeMapper, TypeMapper, Structure field mapping) with a class that is not a NativeMapped implementation.","commonSituations":"Passing the wrong class to a custom TypeMapper; typos in generic types; refactoring removed the implements NativeMapped clause while the mapper still references the type.","solutions":["Make the class implement com.sun.jna.NativeMapped (toNative, fromNative, nativeType methods)","Check that the type passed to the mapper/converter is the intended NativeMapped subclass","Remove the erroneous type from the type mapper registration"],"exampleFix":"// before\nclass MyType { } // not NativeMapped\nnew NativeMappedConverter(MyType.class);\n// after\nclass MyType implements NativeMapped {\n    public Object toNative() { return ...; }\n    public Object fromNative(Object nativeValue, FromNativeContext context) { return ...; }\n    public Class<?> nativeType() { return ...; }\n}","handlingStrategy":"type-guard","validationCode":"if (!NativeMapped.class.isAssignableFrom(type)) {\n    throw new IllegalArgumentException(type + \" must implement NativeMapped\");\n}","typeGuard":"static boolean isNativeMapped(Class<?> c) {\n    return NativeMapped.class.isAssignableFrom(c);\n}","tryCatchPattern":null,"preventionTips":["Implement NativeMapped on every custom type handed to a TypeMapper","Review mapper registrations after refactors"],"tags":["jna","type-mapping","invalid-argument","nativemapped"],"backgroundTag":"incompatible-source-type","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}