java-native-access/jna · error · IllegalArgumentException

must be set from byte/byte[]

Error message

 must be set from byte/byte[]

What it means

For EvtVarTypeSByte and EvtVarTypeByte, setValue accepts a byte[] (array form) or a single byte (stored in byteValue). Values of other types raise IllegalArgumentException '<TypeName> must be set from byte/byte[]'.

Source

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

                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from String/String[]");
                        }
                        break;
                    case EvtVarTypeSByte:
                    case EvtVarTypeByte:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == byte.class) {
                            Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY;
                            Memory mem = new Memory(((byte[]) value).length * 1);
                            mem.write(0, (byte[]) value, 0, ((byte[]) value).length);
                            holder = mem;
                            Count = 0;
                            field1.writeField("pointerValue", mem);
                        } else if (value.getClass() == byte.class) {
                            Type = type.ordinal();
                            Count = 0;
                            field1.writeField("byteValue", value);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from byte/byte[]");
                        }
                        break;
                    case EvtVarTypeInt16:
                    case EvtVarTypeUInt16:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == short.class) {
                            Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY;
                            Memory mem = new Memory(((short[]) value).length * 2);
                            mem.write(0, (short[]) value, 0, ((short[]) value).length);
                            holder = mem;
                            Count = 0;
                            field1.writeField("pointerValue", mem);
                        } else if (value.getClass() == short.class) {
                            Type = type.ordinal();
                            Count = 0;
                            field1.writeField("shortValue", value);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from short/short[]");
                        }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Pass a primitive byte (autoboxing to Byte will NOT pass the check, so use byte[] or ensure exact class)
  2. Wrap a single value in a one-element array: new byte[]{ b }
  3. Convert numeric types with an explicit cast: (byte) intValue, or copy ByteBuffer via buf.get(new byte[buf.remaining()])

Example fix

// before
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeByte, byteBuffer);
// after
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeByte, bytes);
Defensive patterns

Strategy: type-guard

Validate before calling

boolean ok = value instanceof Byte
    ? false /* wrapper rejected: check exact class */
    : value != null && (value.getClass() == byte.class || value.getClass() == byte[].class);
if (value instanceof Byte) value = new byte[]{ ((Byte) value).byteValue() };

Type guard

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

Try / catch

try {
    variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeByte, value);
} catch (IllegalArgumentException e) {
    variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeByte, new byte[]{ ((Number) value).byteValue() });
}

Prevention

When it happens

Trigger: setValue(EVT_VARIANT_TYPE.EvtVarTypeByte, Byte.valueOf((byte)1)) or passing an int/Integer/byte-buffer contents instead of a primitive byte or byte[].

Common situations: Passing a ByteBuffer's backing data without array(); passing Integer parsed from config for a byte-typed channel property; passing Byte wrapper object which fails the getClass() == byte.class check.

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/fa5f73e7a3b36600. Report an issue: GitHub.