java-native-access/jna · error · IllegalArgumentException

Can't determine size of nested structure

Error message

Can't determine size of nested structure

What it means

JNA's Structure.initializeField() creates a placeholder instance of a nested (by-value) Structure field to determine its native size. When the nested structure's own constructor throws IllegalArgumentException (e.g. because its fields cannot be sized or instantiated), initializeField wraps it as "Can't determine size of nested structure". It indicates a field-layout problem in an embedded structure, not in the outer one.

Source

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

                }
            }
            catch (Exception e) {
                throw new Error("Exception reading field '" + f.getName() + "' in " + getClass(), e);
            }
        }
    }

    private Object initializeField(Field field, Class<?> type) {
        Object value = null;
        if (Structure.class.isAssignableFrom(type)
            && !(ByReference.class.isAssignableFrom(type))) {
            try {
                value = newInstance((Class<? extends Structure>) type, PLACEHOLDER_MEMORY);
                setFieldValue(field, value);
            }
            catch(IllegalArgumentException e) {
                String msg = "Can't determine size of nested structure";
                throw new IllegalArgumentException(msg, e);
            }
        }
        else if (NativeMapped.class.isAssignableFrom(type)) {
            NativeMappedConverter tc = NativeMappedConverter.getInstance(type);
            value = tc.defaultValue();
            setFieldValue(field, value);
        }
        return value;
    }

    private int addPadding(int calculatedSize) {
        return addPadding(calculatedSize, structAlignment);
    }

    private int addPadding(int calculatedSize, int alignment) {
        // Structure size must be an integral multiple of its alignment,
        // add padding if necessary.
        if (actualAlignType != ALIGN_NONE) {

View on GitHub (pinned to d036ad9781)

Solutions

  1. Fix the root IllegalArgumentException in the cause chain - it names the nested Structure class that failed to instantiate or size.
  2. Make the nested Structure class and its no-arg and (Pointer) constructors public and static (non-static inner classes cannot be instantiated reflectively).
  3. Ensure every field in the nested Structure has a supported JNA type with a determinable native size.
  4. If the member is really a pointer to a struct, change the field type to extend Structure.ByReference so JNA only needs pointer size.

Example fix

// before
class Outer extends Structure {
    private Inner inner; // non-public, non-static nested struct
}
// after
public static class Inner extends Structure { public int x; protected void getFieldOrder() {...} }
class Outer extends Structure {
    public Inner inner;
}
Defensive patterns

Strategy: validation

Validate before calling

static <T extends Structure> void checkEmbeddable(Class<T> nested) {
    if (java.lang.reflect.Modifier.isAbstract(nested.getModifiers()))
        throw new IllegalStateException(nested + " must be concrete to embed by value");
    if (nested.isMemberClass() && !java.lang.reflect.Modifier.isStatic(nested.getModifiers()))
        throw new IllegalStateException(nested + " must be a static class");
    try { nested.getConstructor(); nested.getConstructor(Pointer.class); }
    catch (NoSuchMethodException e) { throw new IllegalStateException(nested + " needs public no-arg and (Pointer) constructors"); }
}

Type guard

static boolean isEmbeddableByValue(Class<?> t) {
    return Structure.class.isAssignableFrom(t)
        && !Structure.ByReference.class.isAssignableFrom(t)
        && !java.lang.reflect.Modifier.isAbstract(t.getModifiers())
        && (t.getEnclosingClass() == null || java.lang.reflect.Modifier.isStatic(t.getModifiers()));
}

Try / catch

try {
    MyOuter outer = new MyOuter();
    outer.size();
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("Can't determine size of nested structure")) {
        // inspect e.getCause() for the failing nested Structure class
        throw new IllegalStateException("Fix nested struct: " + e.getCause(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Declaring a Structure with a non-ByReference nested Structure field whose class cannot be instantiated or sized during calculateSize(): e.g. the nested structure throws in its field initialization, has a non-public default/Pointer constructor, or contains fields with no computable native size.

Common situations: Embedding an abstract or inner (non-static) Structure class as a by-value field; nested struct with a field of an unsupported type; nested Structure subclass whose constructor performs validation and throws IllegalArgumentException; refactor changing a nested class to non-public while keeping it a by-value member.

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