java-native-access/jna · error · IllegalArgumentException
Structure size must be greater than zero: " + size
Error message
Structure size must be greater than zero: " + size
What it means
Structure.allocateMemory(int) rejects non-positive sizes with this IllegalArgumentException. When allocateMemory is called with an explicit size (not CALCULATE_SIZE), that size must be positive because JNA cannot allocate a zero- or negative-length native block for the structure.
Solutions
- Give the Structure at least one mappable public instance field (JNA-aligned types), so calculateSize() returns a positive size.
- If calling allocateMemory manually, pass a positive byte count (or Structure.CALCULATE_SIZE to defer to layout analysis).
- Check that field types are supported JNA types (int, long, Pointer, Structure, etc.); unsupported fields are skipped and can leave the size at 0.
- Ensure the subclass is fully initialized when allocateMemory runs — fields added after allocation can yield 0 size; call calculateSize(true) to diagnose.
Example fix
// before
class Empty extends Structure {
private int hidden; // not public -> size 0
}
new Empty().allocateMemory(0); // IllegalArgumentException
// after
class Empty extends Structure {
public int value; // mappable field -> positive size
}
new Empty().allocateMemory(new Empty().size()); Defensive patterns
Strategy: validation
Validate before calling
int size = structure.calculateSize(false);
if (size <= 0) {
throw new IllegalStateException("structure has no mappable fields; size=" + size);
} Type guard
static boolean hasMappableFields(Structure s) { return !s.getFields().isEmpty(); } Try / catch
try {
allocateMemory(requestedSize);
} catch (IllegalArgumentException e) {
int computed = calculateSize(true);
if (computed > 0) allocateMemory(computed);
else throw new IllegalStateException("no mappable fields in " + getClass(), e);
} Prevention
- Ensure every Structure has at least one public, non-static, JNA-supported instance field.
- Never hard-code 0 or negative sizes in allocateMemory overrides; use CALCULATE_SIZE.
- Verify all field types are JNA-mappable when a struct unexpectedly computes size 0.
When it happens
Trigger: Calling the protected allocateMemory(size) with size <= 0 from a subclass (e.g. custom allocateMemory logic or a Structure subclass overriding size calculation), or calculateSize(false) returning a non-positive value that then flows into allocation.
Common situations: Structures whose calculateSize returns 0 because they have no public/recognized fields (all fields non-public, static, or of unsupported types); subclasses that hard-code a size of 0; structs with only transient/ignored fields.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- No such field: " + name
- Array fields must be initialized
- Bad volume GUID path format:
- Byte boundary must be positive
- Can't determine size of nested structure
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/2bf0ba381872c36c.
Report an issue: GitHub.
Appendix: source
Thrown at src/com/sun/jna/Structure.java:433
private void allocateMemory(boolean avoidFFIType) {
allocateMemory(calculateSize(true, avoidFFIType));
}
/** Provided for derived classes to indicate a different
* size than the default. Returns whether the operation was successful.
* Will leave memory untouched if it is non-null and not allocated
* by this class.
* @param size how much memory to allocate
*/
protected void allocateMemory(int size) {
if (size == CALCULATE_SIZE) {
// Analyze the struct, but don't worry if we can't yet do it
size = calculateSize(false);
}
else if (size <= 0) {
throw new IllegalArgumentException("Structure size must be greater than zero: " + size);
}
// May need to defer size calculation if derived class not fully
// initialized
if (size != CALCULATE_SIZE) {
if (this.memory == null
|| this.memory instanceof AutoAllocated) {
this.memory = autoAllocate(size);
}
this.size = size;
}
}
/** Returns the size in memory occupied by this Structure.
* @return Native size of this structure, in bytes.
*/
public int size() {
ensureAllocated();
return this.size;View on GitHub (pinned to d036ad9781)