java-native-access/jna · error · IllegalArgumentException
Structure array must have non-zero length
Error message
Structure array must have non-zero length
What it means
A zero-length Structure array cannot be marshaled because JNA derives the native pointer from the first element (ss[0].getPointer()); there is no element to take an address from. JNA therefore rejects empty arrays with IllegalArgumentException.
Source
Thrown at src/com/sun/jna/Function.java:615
for (int i=0;i < ss.length;i++) {
if (ss[i] instanceof Structure.ByReference) {
throw new IllegalArgumentException("Function " + getName()
+ " declared Structure[] at parameter "
+ index + " but element " + i
+ " is of Structure.ByReference type");
}
}
}
}
if (byRef) {
Structure.autoWrite(ss);
Pointer[] pointers = new Pointer[ss.length + 1];
for (int i=0;i < ss.length;i++) {
pointers[i] = ss[i] != null ? ss[i].getPointer() : null;
}
return new PointerArray(pointers);
} else if (ss.length == 0) {
throw new IllegalArgumentException("Structure array must have non-zero length");
} else if (ss[0] == null) {
Structure.newInstance((Class<? extends Structure>) type).toArray(ss);
return ss[0].getPointer();
} else {
Structure.autoWrite(ss);
return ss[0].getPointer();
}
} else if (argClass.isArray()){
throw new IllegalArgumentException("Unsupported array argument type: "
+ argClass.getComponentType());
} else if (allowObjects) {
return arg;
} else if (!Native.isSupportedNativeType(arg.getClass())) {
throw new IllegalArgumentException("Unsupported argument type "
+ arg.getClass().getName()
+ " at parameter " + index
+ " of function " + getName());
}View on GitHub (pinned to d036ad9781)
Solutions
- Guard the call site: if the array is empty, pass Pointer.NULL (or null) instead of an empty Structure[]
- Model the native API as (Pointer, int count) and pass null plus 0 for the empty case
- Allocate at least one element if the native API requires a real array (even a dummy)
Example fix
// before f(new MyStruct[0]); // after f(items.isEmpty() ? null : items.toArray(new MyStruct[0]));
Defensive patterns
Strategy: validation
Validate before calling
if (ss.length == 0) {
nativeCall(null, 0); // or pass Pointer.NULL per your API mapping
} else {
nativeCall(ss, ss.length);
} Try / catch
try {
f.invoke(...);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("non-zero length")) { /* pass NULL/0 instead */ }
} Prevention
- Model native (ptr,count) pairs explicitly and pass null/0 for empty sets
- Always check collection size at the boundary before converting to Structure[]
When it happens
Trigger: Passing new MyStruct[0] (or a List.toArray into an empty array) as a Structure[] argument to a native function.
Common situations: Passing a Java-side empty collection result straight into a native call without a null-pointer / count protocol; native API expecting (NULL, 0) pattern that the Java mapping doesn't model.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Function <name> declared Structure[] at parameter <index> bu
- Function <name> declared Structure[] at parameter <index> bu
- The given priority value is invalid!
- must be set from byte[]
- Unrecognized calling convention: <convention>
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/3603212d335ff0c2.
Report an issue: GitHub.