{"record":{"id":"f6a4f0d5f6aa0c2d","repo":"java-native-access/jna","slug":"fieldname-must-be-a-public-field-of-type-resultclass-getname","errorCode":null,"errorMessage":"fieldName must be a public field of type resultClass.getName() (e): mappingClass","messagePattern":"fieldName must be a public field of type resultClass\\.getName\\(\\) \\(e\\): mappingClass","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Native.java","lineNumber":883,"sourceCode":"        libraryOptions = cacheOptions(mappingClass, libraryOptions, null);\n        // Store the original lookup class, if different from the mapping class\n        if (type != mappingClass) {\n            typeOptions.put(type, libraryOptions);\n        }\n        return libraryOptions;\n    }\n\n    private static Object lookupField(Class<?> mappingClass, String fieldName, Class<?> resultClass) {\n        try {\n            Field field = mappingClass.getField(fieldName);\n            field.setAccessible(true);\n            return field.get(null);\n        }\n        catch (NoSuchFieldException e) {\n            return null;\n        }\n        catch (Exception e) {\n            throw new IllegalArgumentException(fieldName + \" must be a public field of type \"\n                                               + resultClass.getName() + \" (\"\n                                               + e + \"): \" + mappingClass);\n        }\n    }\n\n    /** Return the preferred {@link TypeMapper} for the given native interface.\n     * See {@link com.sun.jna.Library#OPTION_TYPE_MAPPER}.\n     */\n    public static TypeMapper getTypeMapper(Class<?> cls) {\n        Map<String, ?> options = getLibraryOptions(cls);\n        return (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER);\n    }\n\n    /**\n     * @param cls The native interface type\n     * @return The preferred string encoding for the given native interface.\n     * If there is no setting, defaults to the {@link #getDefaultStringEncoding()}.\n     * @see com.sun.jna.Library#OPTION_STRING_ENCODING","sourceCodeStart":865,"sourceCodeEnd":901,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Native.java#L865-L901","documentation":"JNA's lookupField helper reads optional public static fields (TYPE_MAPPER, STRUCTURE_ALIGNMENT, STRING_ENCODING) from a library mapping class. If the field exists but cannot be accessed or its value's type does not match the expected resultClass, it throws this IllegalArgumentException naming the field, expected type, and mapping class. A missing field is fine (returns null); a present-but-invalid field is not.","triggerScenarios":"Declaring a public static field named TYPE_MAPPER (must be TypeMapper/FieldMapper or TypeMapper.Provider), STRUCTURE_ALIGNMENT (must be Integer), or STRING_ENCODING (must be String) with the wrong type, non-static, or a throwing initializer, then loading the library.","commonSituations":"Typing TYPE_MAPPER as a concrete class not implementing TypeMapper; making STRUCTURE_ALIGNMENT a raw int instead of Integer; STRING_ENCODING initialized with a non-String; initializer exceptions surfacing as the embedded cause.","solutions":["Correct the field's declared type to match the required type (TypeMapper, Integer, or String respectively) and make it public static","Delete the field if the customization is unnecessary (absence is allowed)","If using a TypeMapper.Provider, ensure it is assignable to the expected type and instantiates cleanly","Check the embedded exception 'e' in the message for the root cause (IllegalAccessException vs ExceptionInInitializerError)"],"exampleFix":"// before\npublic static int STRUCTURE_ALIGNMENT = Structure.ALIGN_DEFAULT;\n// after\npublic static final Integer STRUCTURE_ALIGNMENT = Integer.valueOf(Structure.ALIGN_DEFAULT);","handlingStrategy":"validation","validationCode":"static void checkOptionalField(Class<?> c, String name, Class<?> expected) throws Exception {\n    try {\n        Field f = c.getField(name);\n        Object v = f.get(null);\n        if (!expected.isInstance(v)) throw new IllegalStateException(name + \" must be \" + expected.getName());\n    } catch (NoSuchFieldException ok) { }\n}\n// usage: checkOptionalField(MyLib.class, \"TYPE_MAPPER\", TypeMapper.class);","typeGuard":"boolean validOptional(Class<?> c, String name, Class<?> expected) {\n    try { Field f = c.getField(name); return expected.isInstance(f.get(null)); } catch (Exception e) { return false; }\n}","tryCatchPattern":"try { Native.load(\"mylib\", MyLib.class); } catch (IllegalArgumentException e) { if (String.valueOf(e.getMessage()).startsWith(\"TYPE_MAPPER must be\")) { throw new IllegalStateException(\"Check TYPE_MAPPER/STRUCTURE_ALIGNMENT/STRING_ENCODING declarations\", e); } throw e; }","preventionTips":["Only add TYPE_MAPPER/STRUCTURE_ALIGNMENT/STRING_ENCODING fields with the exact documented types","Use Integer (not int) for STRUCTURE_ALIGNMENT","Ensure optional fields are public static and their initializers cannot throw"],"tags":["java","reflection","type-mismatch","library-options"],"backgroundTag":"type-mismatch","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}