{"record":{"id":"77f0cb61c3f81a4e","repo":"java-native-access/jna","slug":"structure-getfieldorder-on-getclass-returns-names-sort","errorCode":null,"errorMessage":"Structure.getFieldOrder() on \" + getClass() + \" returns names (\" + sort(fieldOrder) + \") which do not match declared field names (\" + sort(names) + \")\"","messagePattern":"Structure\\.getFieldOrder\\(\\) on \" \\+ getClass\\(\\) \\+ \" returns names \\(\" \\+ sort\\(fieldOrder\\) \\+ \"\\) which do not match declared field names \\(\" \\+ sort\\(names\\) \\+ \"\\)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Structure.java","lineNumber":1154,"sourceCode":"            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 (\"\n                            + sort(fieldOrder)\n                            + \") which do not match declared field names (\"\n                            + sort(names) + \")\");\n        }\n\n        sortFields(flist, fieldOrder);\n        return flist;\n    }\n\n    /** Calculate the amount of native memory required for this structure.\n     * May return {@link #CALCULATE_SIZE} if the size can not yet be\n     * determined (usually due to fields in the derived class not yet\n     * being initialized).\n     * If the <code>force</code> parameter is <code>true</code> will throw\n     * an {@link IllegalStateException} if the size can not be determined.\n     * @param force whether to force size calculation\n     * @return calculated size, or {@link #CALCULATE_SIZE} if the size can not","sourceCodeStart":1136,"sourceCodeEnd":1172,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L1136-L1172","documentation":"After counting, JNA compares the set of names returned by getFieldOrder() with the actual declared field names and throws this Error if the sets differ. Names must match exactly (same spelling), even if counts are equal — the check catches wrong or renamed entries in the declared order.","triggerScenarios":"getFieldOrder() returns names that don't correspond to any declared field (typo, old name) or omits a declared field while including another of equal count; renaming a Java field without updating getFieldOrder().","commonSituations":"IDE refactors renaming a field but leaving the string list in getFieldOrder()/@FieldOrder untouched; copy-paste between structure classes with different field names; case mismatches.","solutions":["Synchronize getFieldOrder() strings with the exact declared Java field names","Re-run/re-generate the @Structure.FieldOrder annotation after any field rename","Keep field declaration and order list adjacent (or use the annotation on the class) to make drift visible in review","Add a unit test constructing each Structure early so validation errors surface at startup"],"exampleFix":"// before\n@Structure.FieldOrder({\"flags\", \"size\"})\npublic int flags, length;\n// after\n@Structure.FieldOrder({\"flags\", \"length\"})\npublic int flags, length;","handlingStrategy":"validation","validationCode":"List order = struct.getFieldOrder();\njava.util.Set declared = java.util.Arrays.stream(struct.getClass().getDeclaredFields())\n    .filter(f -> !java.lang.reflect.Modifier.isStatic(f.getModifiers()))\n    .map(java.lang.reflect.Field::getName).collect(java.util.stream.Collectors.toSet());\nif (!new java.util.HashSet<>(order).equals(declared)) throw new IllegalStateException(\"getFieldOrder names do not match declared fields\");","typeGuard":null,"tryCatchPattern":"try { new MyStructure(); } catch (Error e) { /* names mismatch: compare e.getMessage() lists and fix getFieldOrder */ }","preventionTips":["Reference fields via method references/compile-time constants when building the order list where possible","Re-run refactoring-aware codegen for @FieldOrder after renames","Add construction tests for every Structure","Keep order list alphabetically diffed in code review against declarations"],"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"}