java-native-access/jna · error · IllegalArgumentException

setValue must not be called with type set to NULL

Error message

setValue must not be called with type set to NULL

What it means

EVT_VARIANT.setValue() in JNA's Winevt helper wraps an EVT_VARIANT union for the Windows Event Log API. It throws IllegalArgumentException when the caller passes a null EVT_VARIANT_TYPE, because without a type there is no way to know which union field to populate. The null check runs before any switch on the type, so this always fails fast.

Solutions

  1. Pass a non-null EVT_VARIANT_TYPE, e.g. EVT_VARIANT_TYPE.EvtVarTypeNull if you intend to clear the variant
  2. If the type comes from a variable or lookup, check for null before calling setValue and substitute EvtVarTypeNull
  3. If clearing the value, call setValue(EVT_VARIANT_TYPE.EvtVarTypeNull, null) instead of passing a null type

Example fix

// before
variant.setValue(null, myValue);
// after
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeString, myValue);
// or to clear:
variant.setValue(EVT_VARIANT_TYPE.EvtVarTypeNull, null);
Defensive patterns

Strategy: validation

Validate before calling

if (type == null) {
    type = EVT_VARIANT_TYPE.EvtVarTypeNull; // or throw a domain-specific error early
}
variant.setValue(type, value);

Type guard

boolean isValidType(EVT_VARIANT_TYPE t) { return t != null; }

Try / catch

try {
    variant.setValue(type, value);
} catch (IllegalArgumentException e) {
    log.warn("Bad EVT_VARIANT type/value: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling setValue(null, someValue) — e.g. passing an uninitialized or lookup-failed EVT_VARIANT_TYPE variable, or a method returning null type to renderChannelConfig/event-rendering code like testModifyChannelConfig.

Common situations: Mapping an EvtVariant field whose type was read from a struct and turned out null; passing the result of a map lookup (get(typeKey)) that missed; refactoring where the type variable was accidentally not initialized.

Related errors


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

Appendix: source

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

        public boolean isArray() {
            return (Type & EVT_VARIANT_TYPE_ARRAY) == EVT_VARIANT_TYPE_ARRAY;
        }

        public EVT_VARIANT_TYPE getVariantType() {
            return EVT_VARIANT_TYPE.values()[getBaseType()];
        }

        // Helper to store java object for set values
        private Object holder;

        /**
         * @param type
         * @param value
         */
        public void setValue(EVT_VARIANT_TYPE type, Object value) {
            allocateMemory();
            if (type == null) {
                throw new IllegalArgumentException("setValue must not be called with type set to NULL");
            }
            holder = null;
            if (value == null || type == EVT_VARIANT_TYPE.EvtVarTypeNull) {
                Type = EVT_VARIANT_TYPE.EvtVarTypeNull.ordinal();
                Count = 0;
                field1.writeField("pointerValue", Pointer.NULL);
            } else {
                switch (type) {
                    case EvtVarTypeAnsiString:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == String.class) {
                            Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY;
                            StringArray sa = new StringArray((String[]) value, false);
                            holder = sa;
                            Count = ((String[]) value).length;
                            field1.writeField("pointerValue", sa);
                        } else if (value.getClass() == String.class) {
                            Type = type.ordinal();
                            Memory mem = new Memory(((String) value).length() + 1);

View on GitHub (pinned to d036ad9781)