{"record":{"id":"0b47ac93eb126ebb","repo":"java-native-access/jna","slug":"return-type-returntype-does-not-match-result-resultclass","errorCode":null,"errorMessage":"Return type <returnType> does not match result <resultClass>","messagePattern":"Return type <returnType> does not match result <resultClass>","errorType":"validation","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Function.java","lineNumber":489,"sourceCode":"            Pointer p = invokePointer(callFlags, args);\n            if (p != null) {\n                String[] arr = p.getWideStringArray(0);\n                WString[] warr = new WString[arr.length];\n                for (int i=0;i < arr.length;i++) {\n                    warr[i] = new WString(arr[i]);\n                }\n                result = warr;\n            }\n        } else if (returnType==Pointer[].class) {\n            Pointer p = invokePointer(callFlags, args);\n            if (p != null) {\n                result = p.getPointerArray(0);\n            }\n        } else if (allowObjects) {\n            result = Native.invokeObject(this, this.peer, callFlags, args);\n            if (result != null\n                && !returnType.isAssignableFrom(result.getClass())) {\n                throw new ClassCastException(\"Return type \" + returnType\n                                             + \" does not match result \"\n                                             + result.getClass());\n            }\n        } else {\n            throw new IllegalArgumentException(\"Unsupported return type \" + returnType + \" in function \" + getName());\n        }\n        return result;\n    }\n\n    private Pointer invokePointer(int callFlags, Object[] args) {\n        long ptr = Native.invokePointer(this, this.peer, callFlags, args);\n        return ptr == 0 ? null : new Pointer(ptr);\n    }\n\n    private Object convertArgument(Object[] args, int index,\n                                   Method invokingMethod, TypeMapper mapper,\n                                   boolean allowObjects, Class<?> expectedType) {\n        Object arg = args[index];","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Function.java#L471-L507","documentation":"When OBJECT_RETURN is allowed, JNA calls Native.invokeObject and then verifies the returned Java object is assignable to the declared return type. If the native code produced an object of an incompatible class, a ClassCastException is thrown describing both types.","triggerScenarios":"Mapping a function with a Java return type T while allowing object returns, and the native callback/library returns an object whose class is not T or a subclass of T (e.g. declared Integer but native returned a String).","commonSituations":"Callback/Object-return APIs where the native side changed what it returns after a library upgrade; misdeclared return type in the Java interface.","solutions":["Correct the declared return type in the Java mapping to match what the native side actually returns","Validate the native return value type before mapping (add logging/debug in the native producer)","If both types are plausible, declare the return as Object and downcast with instanceof checks"],"exampleFix":"// before\nString getValue(); // native returns Integer\n// after\nObject getValue(); // then cast after instanceof check","handlingStrategy":"type-guard","validationCode":"Object r = Native.invokeObject(f, peer, flags, args);\nif (r != null && !expectedType.isAssignableFrom(r.getClass())) {\n    throw new IllegalStateException(\"unexpected return \" + r.getClass());\n}","typeGuard":"static <T> T safeCast(Object r, Class<T> t) {\n    return t.isInstance(r) ? t.cast(r) : null;\n}","tryCatchPattern":"try {\n    result = f.invoke(...);\n} catch (ClassCastException e) {\n    // declared return type does not match the object returned by native side\n}","preventionTips":["Keep the Java return type in sync with what the native side actually produces","Prefer declaring Object and narrowing with instanceof when the native return is dynamic"],"tags":["jna","class-cast","type-mismatch","return-type"],"backgroundTag":"type-mismatch","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"}