java-native-access/jna · error · IllegalStateException

Type not supported

Error message

Type not supported: <vartype>

What it means

OaIdlUtil.toPrimitiveArray allocates the target primitive array with a switch over the requested VAREnum varType; VT_UNKNOWN, VT_DISPATCH, VT_CY, VT_DECIMAL, VT_RECORD and unknown types hit `default` and throw IllegalStateException 'Type not supported'.

Solutions

  1. Only call toPrimitiveArray for supported varTypes (numeric, boolean, BSTR etc.) and special-case unsupported ones
  2. Read VT_DECIMAL/VT_CY/VT_UNKNOWN elements manually via SAFEARRAY.getElement and Variant wrappers
  3. Convert the SAFEARRAY server-side to a supported element type
  4. Extend the switch in a fork to add the missing type

Example fix

// before
Object[] r = OaIdlUtil.toPrimitiveArray(sa, VAREnum.VT_DECIMAL);
// after
if (sa.getVarType().intValue() == VAREnum.VT_DECIMAL) {
    List<DECIMAL> r = readDecimalsManually(sa);
} else {
    Object[] r = OaIdlUtil.toPrimitiveArray(sa);
}
Defensive patterns

Strategy: type-guard

Validate before calling

int vt = varType;
boolean supported = !(vt==VAREnum.VT_UNKNOWN||vt==VAREnum.VT_DISPATCH||vt==VAREnum.VT_CY||vt==VAREnum.VT_DECIMAL||vt==VAREnum.VT_RECORD);

Type guard

boolean toPrimitiveSupported(int vartype) {
    return !(vartype == VAREnum.VT_UNKNOWN || vartype == VAREnum.VT_DISPATCH
          || vartype == VAREnum.VT_CY || vartype == VAREnum.VT_DECIMAL
          || vartype == VAREnum.VT_RECORD);
}

Try / catch

try {
    return OaIdlUtil.toPrimitiveArray(sa);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Type not supported")) return readManually(sa);
    throw e;
}

Prevention

When it happens

Trigger: Calling toPrimitiveArray with varType set to VT_UNKNOWN, VT_DISPATCH, VT_CY, VT_DECIMAL, VT_RECORD, or any value with no case in the switch.

Common situations: Converting arrays of COM interface pointers or currency/decimal values; assuming the utility handles all VAREnum types; a COM server changed its return type after an upgrade.

Related errors


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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/OaIdlUtil.java:168

                    break;
                case VT_R8:
                case VT_DATE:
                    sourceArray = dataPointer.getDoubleArray(0, elementCount);
                    break;
                case VT_BSTR:
                    sourceArray = dataPointer.getPointerArray(0, elementCount);
                    break;
                case VT_VARIANT:
                    VARIANT variant = new VARIANT(dataPointer);
                    sourceArray = variant.toArray(elementCount);
                    break;
                case VT_UNKNOWN:
                case VT_DISPATCH:
                case VT_CY:
                case VT_DECIMAL:
                case VT_RECORD:
                default:
                    throw new IllegalStateException("Type not supported: " + varType);
            }

            Object targetArray = Array.newInstance(Object.class, elements);
            toPrimitiveArray(sourceArray, targetArray, elements, cumElements, varType, new int[0]);
            return targetArray;
        } finally {
            sa.unaccessData();
            if (destruct) {
                sa.destroy();
            }
        }
    }

    private static void toPrimitiveArray(Object dataArray, Object targetArray, int[] elements, int[] cumElements, int varType, int[] currentIdx) {
        int dimIdx = currentIdx.length;
        int[] subIdx = new int[currentIdx.length + 1];
        System.arraycopy(currentIdx, 0, subIdx, 0, dimIdx);
        for (int i = 0; i < elements[dimIdx]; i++) {

View on GitHub (pinned to d036ad9781)