java-native-access/jna · error · Error

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

Error message

Structure.getFieldOrder() on " + getClass() + " returns names (" + sort(fieldOrder) + ") which do not match declared field names (" + sort(names) + ")"

What it means

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.

Solutions

  1. Synchronize getFieldOrder() strings with the exact declared Java field names
  2. Re-run/re-generate the @Structure.FieldOrder annotation after any field rename
  3. Keep field declaration and order list adjacent (or use the annotation on the class) to make drift visible in review
  4. Add a unit test constructing each Structure early so validation errors surface at startup

Example fix

// before
@Structure.FieldOrder({"flags", "size"})
public int flags, length;
// after
@Structure.FieldOrder({"flags", "length"})
public int flags, length;
Defensive patterns

Strategy: validation

Validate before calling

List order = struct.getFieldOrder();
java.util.Set declared = java.util.Arrays.stream(struct.getClass().getDeclaredFields())
    .filter(f -> !java.lang.reflect.Modifier.isStatic(f.getModifiers()))
    .map(java.lang.reflect.Field::getName).collect(java.util.stream.Collectors.toSet());
if (!new java.util.HashSet<>(order).equals(declared)) throw new IllegalStateException("getFieldOrder names do not match declared fields");

Try / catch

try { new MyStructure(); } catch (Error e) { /* names mismatch: compare e.getMessage() lists and fix getFieldOrder */ }

Prevention

When it happens

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

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

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/77f0cb61c3f81a4e. Report an issue: GitHub.

Appendix: source

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

            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 ("
                            + sort(fieldOrder)
                            + ") which do not match declared field names ("
                            + sort(names) + ")");
        }

        sortFields(flist, fieldOrder);
        return flist;
    }

    /** Calculate the amount of native memory required for this structure.
     * May return {@link #CALCULATE_SIZE} if the size can not yet be
     * determined (usually due to fields in the derived class not yet
     * being initialized).
     * If the <code>force</code> parameter is <code>true</code> will throw
     * an {@link IllegalStateException} if the size can not be determined.
     * @param force whether to force size calculation
     * @return calculated size, or {@link #CALCULATE_SIZE} if the size can not

View on GitHub (pinned to d036ad9781)