java-native-access/jna · error · IllegalArgumentException

Nested Structure arrays must use a derived Structure type so

Error message

Nested Structure arrays must use a derived Structure type so that the size of the elements can be determined

What it means

A nested Structure array field must use a derived Structure type (a concrete subclass), not the abstract Structure base class, because JNA needs the concrete class to determine each element's native size. Declaring Structure[] is rejected with IllegalArgumentException.

Source

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

                // fields
                field.setAccessible(true);
            }
            structField.field = field;
            structField.name = field.getName();
            structField.type = type;

            // Check for illegal field types
            if (Callback.class.isAssignableFrom(type) && !type.isInterface()) {
                throw new IllegalArgumentException("Structure Callback field '"
                                                   + field.getName()
                                                   + "' must be an interface");
            }
            if (type.isArray()
                && Structure.class.equals(type.getComponentType())) {
                String msg = "Nested Structure arrays must use a "
                    + "derived Structure type so that the size of "
                    + "the elements can be determined";
                throw new IllegalArgumentException(msg);
            }

            int fieldAlignment = 1;
            if (!Modifier.isPublic(field.getModifiers())) {
                continue;
            }

            Object value = getFieldValue(structField.field);
            if (value == null && type.isArray()) {
                if (force) {
                    throw new IllegalStateException("Array fields must be initialized");
                }
                // can't calculate size yet, defer until later
                return null;
            }
            Class<?> nativeType = type;
            if (NativeMapped.class.isAssignableFrom(type)) {
                NativeMappedConverter tc = NativeMappedConverter.getInstance(type);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Define a concrete Structure subclass and declare the array with that type (e.g. public Point[] points)
  2. If element sizes differ, model with Pointer plus manual reads, or several typed array fields
  3. For unions of element types, pick a single concrete representative or use a union-based approach

Example fix

// before
class List extends Structure {
    public Structure[] entries; // unknown element size
}
// after
class List extends Structure {
    public Entry[] entries;
}
class Entry extends Structure { public int id; }
Defensive patterns

Strategy: type-guard

Validate before calling

for (Field f : S.class.getFields()) {
    Class<?> t = f.getType();
    if (t.isArray() && t.getComponentType() == Structure.class) {
        throw new IllegalStateException(f + " must use a derived Structure type");
    }
}

Type guard

static boolean isValidArrayField(Class<?> t) {
    return !t.isArray() || !Structure.class.equals(t.getComponentType());
}

Try / catch

try {
    s.size();
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("Nested Structure arrays")) {
        throw new IllegalStateException("Use a concrete Structure subclass for array elements", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Declaring a field like public Structure[] items; where getComponentType() equals exactly Structure.class (not a subclass).

Common situations: Writing generic container structures without knowing concrete element types; converting C code with flexible arrays too literally; forgetting to define a concrete Structure subclass for the array elements.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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