java-native-access/jna · error · Error

Structure.getFieldOrder() on " + getClass() +…

Error message

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) + ")"

What it means

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.

Solutions

  1. Update getFieldOrder() to return exactly one entry per declared field, in native memory order
  2. Regenerate the @Structure.FieldOrder annotation value after adding/removing fields
  3. Check parent classes: include inherited mapped fields in the order list
  4. Only declare multiple fields when >1 fields exist — single-field structures are exempt per the flist.size() > 1 condition, so split or reduce otherwise

Example fix

// before
protected List getFieldOrder() { return Arrays.asList("a", "b"); }
public int a, b, c;
// after
@Structure.FieldOrder({"a", "b", "c"})
// or: return Arrays.asList("a", "b", "c");
Defensive patterns

Strategy: validation

Validate before calling

List order = struct.getFieldOrder();
long declared = java.util.Arrays.stream(struct.getClass().getDeclaredFields())
    .filter(f -> !java.lang.reflect.Modifier.isStatic(f.getModifiers())).count();
if (declared > 1 && order.size() != declared) throw new IllegalStateException("getFieldOrder size mismatch");

Try / catch

try { new MyStructure(); } catch (Error e) { /* field order count mismatch: fix getFieldOrder/FieldOrder */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/cd3a165f23fb9168. Report an issue: GitHub.

Appendix: source

Thrown at src/com/sun/jna/Structure.java:1137

    /** Returns all field names (sorted) provided so far by
        {@link #getFieldOrder}
        @param force set if results are required immediately
        @return null if not yet able to provide fields, and force is false.
        @throws Error if force is true and field order data not yet specified
        and can't be generated automatically.
    **/
    protected List<Field> getFields(boolean force) {
        List<Field> flist = new ArrayList<>(getFieldList());
        Set<String> names = new HashSet<>();
        for (Field f : flist) {
            names.add(f.getName());
        }

        List<String> fieldOrder = fieldOrder();
        if (fieldOrder.size() != flist.size() && flist.size() > 1) {
            if (force) {
                throw new Error("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)
                                + ")");
            }
            return null;
        }

        Set<String> orderedNames = new HashSet<>(fieldOrder);
        if (!orderedNames.equals(names)) {
            throw new Error("Structure.getFieldOrder() on " + getClass()
                            + " returns names ("

View on GitHub (pinned to d036ad9781)