java-native-access/jna · error · IllegalArgumentException

Writing array of " + cls + " to memory not supported

Error message

Writing array of " + cls + " to memory not supported

What it means

Pointer.writeArray reached an array element type it cannot serialize into native memory. All supported component types (primitives, Pointer, Structure, NativeMapped) are handled earlier; anything else falls through to this IllegalArgumentException.

Source

Thrown at src/com/sun/jna/Pointer.java:969

                    if (sbuf[i] == null) {
                        sbuf[i] = tmp[i];
                    } else {
                        sbuf[i].useMemory(this, (int)(offset + i * sbuf[i].size()), true);
                    }
                    sbuf[i].write();
                }
            }
        } else if (NativeMapped.class.isAssignableFrom(cls)) {
            NativeMapped[] buf = (NativeMapped[])value;
            NativeMappedConverter tc = NativeMappedConverter.getInstance(cls);
            Class<?> nativeType = tc.nativeType();
            int size = Native.getNativeSize(value.getClass(), value) / buf.length;
            for (int i=0;i < buf.length;i++) {
                Object element = tc.toNative(buf[i], new ToNativeContext());
                setValue(offset + i*size, element, nativeType);
            }
        } else {
            throw new IllegalArgumentException("Writing array of "
                                               + cls + " to memory not supported");
        }
    }

    /** Write <code>value</code> to the requested bank of memory.
     * @param offset byte offset from pointer to start
     * @param length number of bytes to write
     * @param value value to be written
     */
    public void setMemory(long offset, long length, byte value) {
        Native.setMemory(this, this.peer, offset, length, value);
    }

    /**
     * Set <code>value</code> at location being pointed to. This is equivalent
     * to the expression
     * <code>*((jbyte *)((char *)Pointer + offset)) = value</code>.
     *

View on GitHub (pinned to d036ad9781)

Solutions

  1. Use arrays with supported component types: primitive arrays, Pointer[], Structure[], or NativeMapped-implementing classes.
  2. For strings-as-pointer-arrays, allocate a Memory of pointers and write each String with pointer.setString manually.
  3. Give the element class a Structure or NativeMapped mapping describing its native layout.
  4. Write the buffer element-by-element with setValue per element using a supported type.

Example fix

// before
pointer.setValue(0, new String[]{"a","b"}, String.class);
// after
Memory arr = new Memory(2 * Native.POINTER_SIZE);
arr.setPointer(0, new NativeString("a").getPointer());
arr.setPointer(Native.POINTER_SIZE, new NativeString("b").getPointer());
Defensive patterns

Strategy: validation

Validate before calling

static void requireWritableArray(Object arr) {
    Class<?> c = arr.getClass().getComponentType();
    boolean ok = c != null && (c.isPrimitive() || Pointer.class.isAssignableFrom(c)
        || Structure.class.isAssignableFrom(c) || NativeMapped.class.isAssignableFrom(c));
    if (!ok) throw new IllegalArgumentException("Cannot write array of " + c);
}

Type guard

static boolean isWritableArray(Object arr) {
    Class<?> c = arr.getClass().getComponentType();
    return c != null && (c.isPrimitive() || Pointer.class.isAssignableFrom(c)
        || Structure.class.isAssignableFrom(c) || NativeMapped.class.isAssignableFrom(c));
}

Try / catch

try {
    pointer.setValue(offset, array, componentType);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Writing array of")) {
        // write elements individually with supported types
    } else throw e;
}

Prevention

When it happens

Trigger: Calling pointer.setValue(offset, arrayOfX, componentClass) — or writing a Structure containing such an array — where the component type is e.g. String[], Object[], or an unmapped custom class.

Common situations: Declaring String[] or interface-typed arrays in a Structure and calling structure.write(); attempting to persist arrays of arbitrary Java objects to a native buffer; generics leaving an erased/unsupported component type.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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