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
- Define a concrete Structure subclass and declare the array with that type (e.g. public Point[] points)
- If element sizes differ, model with Pointer plus manual reads, or several typed array fields
- 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
- Always use concrete Structure subclasses for array element types
- Never declare Structure[] fields
- Model C flexible arrays with a max-size typed array plus explicit length
- Unit-test size() of every structure
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
- Arrays of length zero not allowed: type
- Need an initialized array
- Array fields must be initialized
- Invalid Structure field in " + getClass() + ", field name '"
- Function <name> declared Structure[] at parameter <index> bu
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/82e5203ab06d14a5.
Report an issue: GitHub.