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

  1. Give the Structure at least one mappable public instance field (JNA-aligned types), so calculateSize() returns a positive size.
  2. If calling allocateMemory manually, pass a positive byte count (or Structure.CALCULATE_SIZE to defer to layout analysis).
  3. Check that field types are supported JNA types (int, long, Pointer, Structure, etc.); unsupported fields are skipped and can leave the size at 0.
  4. 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

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


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)