{"record":{"id":"cd3a165f23fb9168","repo":"java-native-access/jna","slug":"structure-getfieldorder-on-getclass-fieldorder-size-flist","errorCode":null,"errorMessage":"Structure.getFieldOrder() on \" + getClass() + (fieldOrder.size() < flist.size() ? \" does not provide enough\" : \" provides too many\") + \" names [\" + fieldOrder.size() + \"] (\" + sort(fieldOrder) + \") to match declared fields [\" + flist.size() + \"] (\" + sort(names) + \")\"","messagePattern":"Structure\\.getFieldOrder\\(\\) on \" \\+ getClass\\(\\) \\+ \\(fieldOrder\\.size\\(\\) < flist\\.size\\(\\) \\? \" does not provide enough\" : \" provides too many\"\\) \\+ \" names \\[\" \\+ fieldOrder\\.size\\(\\) \\+ \"\\] \\(\" \\+ sort\\(fieldOrder\\) \\+ \"\\) to match declared fields \\[\" \\+ flist\\.size\\(\\) \\+ \"\\] \\(\" \\+ sort\\(names\\) \\+ \"\\)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Structure.java","lineNumber":1137,"sourceCode":"\n    /** Returns all field names (sorted) provided so far by\n        {@link #getFieldOrder}\n        @param force set if results are required immediately\n        @return null if not yet able to provide fields, and force is false.\n        @throws Error if force is true and field order data not yet specified\n        and can't be generated automatically.\n    **/\n    protected List<Field> getFields(boolean force) {\n        List<Field> flist = new ArrayList<>(getFieldList());\n        Set<String> names = new HashSet<>();\n        for (Field f : flist) {\n            names.add(f.getName());\n        }\n\n        List<String> fieldOrder = fieldOrder();\n        if (fieldOrder.size() != flist.size() && flist.size() > 1) {\n            if (force) {\n                throw new Error(\"Structure.getFieldOrder() on \" + getClass()\n                                + (fieldOrder.size() < flist.size()\n                                    ? \" does not provide enough\"\n                                    : \" provides too many\")\n                                + \" names [\" + fieldOrder.size()\n                                + \"] (\"\n                                + sort(fieldOrder)\n                                + \") to match declared fields [\" + flist.size()\n                                + \"] (\"\n                                + sort(names)\n                                + \")\");\n            }\n            return null;\n        }\n\n        Set<String> orderedNames = new HashSet<>(fieldOrder);\n        if (!orderedNames.equals(names)) {\n            throw new Error(\"Structure.getFieldOrder() on \" + getClass()\n                            + \" returns names (\"","sourceCodeStart":1119,"sourceCodeEnd":1155,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L1119-L1155","documentation":"During field-order validation, if Structure.getFieldOrder() returns a different number of names than the number of declared fields (and there is more than one field) and force is set, JNA throws this Error. Subclasses must override getFieldOrder() to list exactly one name per declared field when field ordering is declared as metadata.","triggerScenarios":"A Structure subclass overrides getFieldOrder() but the returned list has fewer or more entries than the declared instance fields; fields were added/removed after writing getFieldOrder(); fields are declared in a parent class so counts differ.","commonSituations":"Adding a native field and forgetting to update getFieldOrder(); using @Structure.FieldOrder annotation generated lists out of sync after refactors; inheritance hierarchies where getFieldOrder only lists subclass fields.","solutions":["Update getFieldOrder() to return exactly one entry per declared field, in native memory order","Regenerate the @Structure.FieldOrder annotation value after adding/removing fields","Check parent classes: include inherited mapped fields in the order list","Only declare multiple fields when >1 fields exist — single-field structures are exempt per the flist.size() > 1 condition, so split or reduce otherwise"],"exampleFix":"// before\nprotected List getFieldOrder() { return Arrays.asList(\"a\", \"b\"); }\npublic int a, b, c;\n// after\n@Structure.FieldOrder({\"a\", \"b\", \"c\"})\n// or: return Arrays.asList(\"a\", \"b\", \"c\");","handlingStrategy":"validation","validationCode":"List order = struct.getFieldOrder();\nlong declared = java.util.Arrays.stream(struct.getClass().getDeclaredFields())\n    .filter(f -> !java.lang.reflect.Modifier.isStatic(f.getModifiers())).count();\nif (declared > 1 && order.size() != declared) throw new IllegalStateException(\"getFieldOrder size mismatch\");","typeGuard":null,"tryCatchPattern":"try { new MyStructure(); } catch (Error e) { /* field order count mismatch: fix getFieldOrder/FieldOrder */ }","preventionTips":["Always update @Structure.FieldOrder when adding/removing fields","Generate the order list from field declarations","Include inherited mapped fields in the count","Instantiate all Structures in unit tests to catch drift"],"tags":["jna","structure","field-order","metadata"],"backgroundTag":"schema-validation-failed","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"}