{"record":{"id":"7449b4b2ed8bbbe4","repo":"java-native-access/jna","slug":"null-options-field","errorCode":null,"errorMessage":"Null options field","messagePattern":"Null options field","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Native.java","lineNumber":847,"sourceCode":"        Class<?> mappingClass = findEnclosingLibraryClass(type);\n        if (mappingClass != null) {\n            loadLibraryInstance(mappingClass);\n        } else {\n            mappingClass = type;\n        }\n\n        libraryOptions = typeOptions.get(mappingClass);\n        if (libraryOptions != null) {\n            typeOptions.put(type, libraryOptions);  // cache for next time\n            return libraryOptions;\n        }\n\n        try {\n            Field field = mappingClass.getField(\"OPTIONS\");\n            field.setAccessible(true);\n            libraryOptions = (Map<String, Object>) field.get(null);\n            if (libraryOptions == null) {\n                throw new IllegalStateException(\"Null options field\");\n            }\n        } catch (NoSuchFieldException e) {\n            libraryOptions = Collections.<String, Object>emptyMap();\n        } catch (Exception e) {\n            throw new IllegalArgumentException(\"OPTIONS must be a public field of type java.util.Map (\" + e + \"): \" + mappingClass);\n        }\n        // Make a clone of the original options\n        libraryOptions = new HashMap<>(libraryOptions);\n        if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) {\n            libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, \"TYPE_MAPPER\", TypeMapper.class));\n        }\n        if (!libraryOptions.containsKey(Library.OPTION_STRUCTURE_ALIGNMENT)) {\n            libraryOptions.put(Library.OPTION_STRUCTURE_ALIGNMENT, lookupField(mappingClass, \"STRUCTURE_ALIGNMENT\", Integer.class));\n        }\n        if (!libraryOptions.containsKey(Library.OPTION_STRING_ENCODING)) {\n            libraryOptions.put(Library.OPTION_STRING_ENCODING, lookupField(mappingClass, \"STRING_ENCODING\", String.class));\n        }\n        libraryOptions = cacheOptions(mappingClass, libraryOptions, null);","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Native.java#L829-L865","documentation":"When initializing a library mapping, JNA reflectively reads the mapping class's public static OPTIONS field and casts it to Map. If the field exists and is accessible but its value is null, JNA throws IllegalStateException('Null options field') because a null options map cannot be defaulted silently on this path.","triggerScenarios":"Declaring 'public static Map<String, Object> OPTIONS;' (or assigning null) in a Library interface and letting Native read it during library setup — field is found via getField(\"OPTIONS\") but its value is null.","commonSituations":"Copy-pasted OPTIONS declaration never initialized; refactoring that replaced the map with null; conditional initialization that didn't run before class load; OPTIONS = null left behind after removing options.","solutions":["Initialize OPTIONS with a non-null map, e.g. Collections.emptyMap() if there are no options.","Remove the OPTIONS field entirely if no options are needed (JNA then uses an empty map).","Populate OPTIONS in a static initializer before the Native load call runs."],"exampleFix":"// before\npublic interface MyLib extends Library {\n    Map<String, Object> OPTIONS = null; // IllegalStateException\n}\n// after\npublic interface MyLib extends Library {\n    Map<String, Object> OPTIONS = Collections.emptyMap();\n}","handlingStrategy":"validation","validationCode":"Object opts = mappingClass.getField(\"OPTIONS\").get(null);\nif (opts == null) {\n    throw new IllegalStateException(\"OPTIONS must be initialized (use Collections.emptyMap(), not null)\");\n}","typeGuard":"boolean hasNonNullOptions(Class<?> c) throws Exception {\n    try {\n        return c.getField(\"OPTIONS\").get(null) != null;\n    } catch (NoSuchFieldException e) {\n        return true; // absence is fine, JNA defaults to empty map\n    }\n}","tryCatchPattern":"try {\n    lib = Native.load(name, mappingClass, options);\n} catch (IllegalStateException e) {\n    if (\"Null options field\".equals(e.getMessage())) {\n        // fix mapping: initialize OPTIONS\n    }\n    throw e;\n}","preventionTips":["Initialize OPTIONS to Collections.emptyMap() rather than leaving it null.","Delete unused OPTIONS fields so JNA applies its empty-map default.","Never assign null to OPTIONS, even temporarily, in a static initializer."],"tags":["jna","options","null-value","library-mapping"],"backgroundTag":"null-argument","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"}