java-native-access/jna · error · IllegalArgumentException

Structure field \"" + structField.name + "\" was declared…

Error message

Structure field \"" + structField.name + "\" was declared as " + structField.type + (structField.type == fieldType ? "" : " (native type " + fieldType + ")") + ", which is not supported within a Structure"

What it means

When JNA validates or marshals a structure field, an inner IllegalArgumentException from the type conversion is rethrown with a message naming the field, its declared Java type, and the attempted native type, explaining that the combination is not supported within a Structure. JNA only supports a fixed set of Java types in structure layouts.

Solutions

  1. Change the field type to a JNA-supported type (primitives, Pointer, String, WString, Buffer, arrays of primitives, nested Structure, Callback, NativeLong, etc.)
  2. Implement NativeMapped on the custom class, or register a TypeMapper via TypeMapper/mapper argument so the type can be converted
  3. Check the wrapped cause (the original IllegalArgumentException) for the exact conversion failure
  4. If using generics/boxed types, replace with the corresponding primitive or JNA numeric wrapper class intended for native sizes

Example fix

// before
class Cfg extends Structure {
    public MyStatus status; // unsupported POJO
}
// after
class Cfg extends Structure {
    public int status; // or implement NativeMapped on MyStatus
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isJnaFieldType(java.lang.Class<?> t) {
    return t.isPrimitive() || com.sun.jna.Pointer.class.isAssignableFrom(t)
        || t == String.class || t == com.sun.jna.WString.class
        || com.sun.jna.Structure.class.isAssignableFrom(t)
        || com.sun.jna.Callback.class.isAssignableFrom(t)
        || com.sun.jna.NativeMapped.class.isAssignableFrom(t)
        || (t.isArray() && isJnaFieldType(t.getComponentType()));
}

Type guard

if (!isJnaFieldType(field.getType()) && mapper == null) {
    throw new IllegalArgumentException("Unsupported structure field type: " + field.getType());
}

Try / catch

try { struct.write(); } catch (IllegalArgumentException e) { /* unsupported field type: inspect e.getMessage() for field name */ }

Prevention

When it happens

Trigger: Declaring a Structure field of an unmapped type (e.g. boolean is supported, but arbitrary POJOs, boxed types not in the supported set, String without proper marshaling hints, arrays of unsupported element types, or a nested object that is neither Structure nor NativeMapped); passing an incompatible native type via a TypeMapper/NativeMapped conversion that itself throws IllegalArgumentException.

Common situations: Custom classes used as fields without implementing NativeMapped or having a TypeMapper; using Integer/Long wrappers instead of primitives in old JNA versions; forgetting to register a TypeMapper on the structure or library; arrays sized incorrectly.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/272f44331c4ea795. Report an issue: GitHub.

Appendix: source

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

                // value is changed, keep the new native string alive
                current.peer = nativeString;
                value = nativeString.getPointer();
            }
            else {
                nativeStrings.remove(structField.name);
            }
        }

        try {
            memory.setValue(offset, value, fieldType);
        }
        catch(IllegalArgumentException e) {
            String msg = "Structure field \"" + structField.name
                + "\" was declared as " + structField.type
                + (structField.type == fieldType
                   ? "" : " (native type " + fieldType + ")")
                + ", which is not supported within a Structure";
            throw new IllegalArgumentException(msg, e);
        }
    }

    /** Used to declare fields order as metadata instead of method.
     * example:
     * <pre><code>
     * // New
     * {@literal @}FieldOrder({ "n", "s" })
     * class Parent extends Structure {
     *     public int n;
     *     public String s;
     * }
     * {@literal @}FieldOrder({ "d", "c" })
     * class Son extends Parent {
     *     public double d;
     *     public char c;
     * }
     * // Old

View on GitHub (pinned to d036ad9781)