java-native-access/jna · error · java.lang.IllegalArgumentException

type is not a supported argument type (in method method.getN

Error message

type is not a supported argument type (in method method.getName() in cls)

What it means

JNA throws this IllegalArgumentException when a native method's parameter type cannot be mapped to a native argument type. During interface registration each parameter is checked with getConversion(); CVT_UNSUPPORTED aborts with the method and class named. This is a setup-time failure, not a call-time one.

Source

Thrown at src/com/sun/jna/Native.java:1957

                case CVT_STRUCTURE:
                case CVT_OBJECT:
                    closure_rtype = rtype = FFIType.get(Pointer.class).getPointer().peer;
                    break;
                case CVT_STRUCTURE_BYVAL:
                    closure_rtype = FFIType.get(Pointer.class).getPointer().peer;
                    rtype = FFIType.get(rclass).getPointer().peer;
                    break;
                default:
                    closure_rtype = rtype = FFIType.get(rclass).getPointer().peer;
            }

            for (int t=0;t < ptypes.length;t++) {
                Class<?> type = ptypes[t];
                sig += getSignature(type);
                int conversionType = getConversion(type, mapper, allowObjects);
                cvt[t] = conversionType;
                if (conversionType == CVT_UNSUPPORTED) {
                    throw new IllegalArgumentException(type + " is not a supported argument type (in method " + method.getName() + " in " + cls + ")");
                }
                if ((conversionType == CVT_NATIVE_MAPPED)
                    || (conversionType == CVT_NATIVE_MAPPED_STRING)
                    || (conversionType == CVT_NATIVE_MAPPED_WSTRING)
                    || (conversionType == CVT_INTEGER_TYPE)) {
                    type = NativeMappedConverter.getInstance(type).nativeType();
                } else if ((conversionType == CVT_TYPE_MAPPER)
                        || (conversionType == CVT_TYPE_MAPPER_STRING)
                        || (conversionType == CVT_TYPE_MAPPER_WSTRING)) {
                    toNative[t] = mapper.getToNativeConverter(type);
                }

                // Determine the type that will be passed to the native
                // function, as well as the type to be passed
                // from Java initially
                switch(conversionType) {
                    case CVT_STRUCTURE_BYVAL:
                    case CVT_INTEGER_TYPE:

View on GitHub (pinned to d036ad9781)

Solutions

  1. Replace the unsupported parameter type with a supported one (int, long, Pointer, Structure, String, byte[]/Buffer, Callback, etc.).
  2. Implement a ToNativeConverter for the class and supply it via a DefaultTypeMapper in the load() options.
  3. Extend NativeMapped/IntegerType for the argument class so JNA can map it natively.
  4. Pass the data through Pointer/Structure explicitly instead of Java objects.

Example fix

// before
int open(File path, int flags); // File unsupported
// after
int open(String path, int flags);
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : MyLib.class.getMethods()) {
    for (Class<?> p : m.getParameterTypes()) {
        boolean ok = p.isPrimitive() || p == String.class
            || Pointer.class.isAssignableFrom(p) || Structure.class.isAssignableFrom(p)
            || p.isArray() || Buffer.class.isAssignableFrom(p)
            || Callback.class.isAssignableFrom(p);
        if (!ok) throw new IllegalStateException(
            "Unsupported argument type " + p + " in " + m);
    }
}

Type guard

boolean isSupportedArg(Class<?> p) {
    return p.isPrimitive() || p == String.class || p.isArray()
        || Buffer.class.isAssignableFrom(p)
        || Pointer.class.isAssignableFrom(p)
        || Structure.class.isAssignableFrom(p)
        || Callback.class.isAssignableFrom(p);
}

Try / catch

try {
    lib = Native.load("mylib", MyLib.class);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("is not a supported argument type")) {
        throw new ConfigurationException("Unsupported parameter type: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Loading or registering a Library interface where any method parameter is of a type JNA cannot convert (e.g. java.io.File, arbitrary POJO, multi-dimensional arrays, autoboxed collections).

Common situations: Writing bindings with signatures like void write(File f) or void process(MyDto dto) without a TypeMapper; migrating code that assumed reflection-based serialization; forgetting a NativeMappedConverter for a custom 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/23009b1d02e62e2f. Report an issue: GitHub.