java-native-access/jna · error · IllegalArgumentException

must be set from int/int[]

Error message

 must be set from int/int[]

What it means

For EvtVarTypeHexInt32, EvtVarTypeInt32 and EvtVarTypeUInt32, setValue requires a primitive int (getClass() == int.class) or an int[] array. Other numeric types (Integer wrapper, long, W32HKEY etc.) raise IllegalArgumentException '<TypeName> must be set from int/int[]'.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Winevt.java:387

                            throw new IllegalArgumentException(type.name() + " must be set from short/short[]");
                        }
                        break;
                    case EvtVarTypeHexInt32:
                    case EvtVarTypeInt32:
                    case EvtVarTypeUInt32:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == int.class) {
                            Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY;
                            Memory mem = new Memory(((int[]) value).length * 4);
                            mem.write(0, (int[]) value, 0, ((int[]) value).length);
                            holder = mem;
                            Count = 0;
                            field1.writeField("pointerValue", mem);
                        } else if (value.getClass() == int.class) {
                            Type = type.ordinal();
                            Count = 0;
                            field1.writeField("intValue", value);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from int/int[]");
                        }
                        break;
                    case EvtVarTypeHexInt64:
                    case EvtVarTypeInt64:
                    case EvtVarTypeUInt64:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == long.class) {
                            Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY;
                            Memory mem = new Memory(((long[]) value).length * 4);
                            mem.write(0, (long[]) value, 0, ((long[]) value).length);
                            holder = mem;
                            Count = 0;
                            field1.writeField("pointerValue", mem);
                        } else if (value.getClass() == long.class) {
                            Type = type.ordinal();
                            Count = 0;
                            field1.writeField("longValue", value);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from long/long[]");

View on GitHub (pinned to d036ad9781)

Solutions

  1. Cast to int: (int) longValue (verify range 0..0xFFFFFFFF for unsigned types first)
  2. Convert Integer[]/List<Integer> into int[] with a loop or IntStream.of(...).toArray()
  3. Pass literals directly — a Java int literal has class int.class and passes

Example fix

// before
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeUInt32, longValue);
// after
if (longValue < 0 || longValue > 0xFFFFFFFFL) throw new IllegalArgumentException("out of UINT32 range");
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeUInt32, (int) longValue);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value instanceof Long) {
    long l = (Long) value;
    if (l < 0 || l > 0xFFFFFFFFL) throw new IllegalArgumentException("UINT32 out of range");
    value = (int) l;
}

Type guard

boolean isIntVariant(Object v) {
    return v != null && (v.getClass() == int.class || v.getClass() == int[].class);
}

Try / catch

try {
    variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeUInt32, value);
} catch (IllegalArgumentException e) {
    variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeUInt32, (int) ((Number) value).longValue());
}

Prevention

When it happens

Trigger: setValue(EVT_VARIANT_TYPE.EvtVarTypeUInt32, longValue) — a long passed for a 32-bit field; or an Integer boxed in a collection, since getClass() is Integer.class not int.class.

Common situations: Values from config parsed as long; counts/flags stored in Long variables; values boxed in ArrayList<Integer> then passed via toArray() producing Integer[].

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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