java-native-access/jna · error · ClassCastException

Unable to cast to CFArray. Type ID

Error message

Unable to cast to CFArray. Type ID: {getTypeID()}

What it means

CFArrayRef's Pointer constructor checks that the wrapped Core Foundation object's type id equals the CFArray type id and throws ClassCastException if not. This guards against narrowing an arbitrary CFTypeRef/Pointer into CFArrayRef.

Solutions

  1. Validate with new CFTypeRef(p).isTypeID(CoreFoundation.ARRAY_TYPE_ID) before constructing CFArrayRef.
  2. Check for NULL pointers before casting (missing key/element).
  3. Remember CFArray elements are CFTypeRefs — inspect each element's type id individually instead of assuming array-ness.
  4. Fix the lookup path if the producer stores a scalar where an array was expected.

Example fix

// before
CFArrayRef arr = new CFArrayRef(value); // throws if value is a CFString
// after
CFTypeRef ref = new CFTypeRef(value);
if (ref.isTypeID(CoreFoundation.ARRAY_TYPE_ID)) {
    CFArrayRef arr = new CFArrayRef(value);
} else {
    // treat as scalar value
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (value != null && new CFTypeRef(value).isTypeID(CoreFoundation.ARRAY_TYPE_ID)) {
    CFArrayRef arr = new CFArrayRef(value);
}

Type guard

boolean isCFArray(Pointer p) {
    return p != null && new CFTypeRef(p).isTypeID(CoreFoundation.ARRAY_TYPE_ID);
}

Try / catch

try {
    CFArrayRef arr = new CFArrayRef(value);
} catch (ClassCastException e) {
    // scalar value where array expected; handle by type
}

Prevention

When it happens

Trigger: Constructing new CFArrayRef(pointer) from a polymorphic result such as a value read from a CFDictionary (e.g. valueForKey returning a CFString) or a NULL pointer whose type id is 0.

Common situations: Reading a dictionary entry expected to be a list but actually a scalar; iterating heterogeneous CFArray elements and mis-casting an element (arrays store CFTypeRefs, not CFArrayRefs); released/invalid pointers.

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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java:316

        }
    }

    /**
     * A reference to an immutable {@code CFArray} object.
     * <p>
     * CFArray is “toll-free bridged” with its Cocoa Foundation counterpart,
     * {@code NSArray}. Therefore, in a method where you see an {@code NSArray *}
     * parameter, you can pass in a {@code CFArrayRef} .
     */
    class CFArrayRef extends CFTypeRef {
        public CFArrayRef() {
            super();
        }

        public CFArrayRef(Pointer p) {
            super(p);
            if (!isTypeID(ARRAY_TYPE_ID)) {
                throw new ClassCastException("Unable to cast to CFArray. Type ID: " + getTypeID());
            }
        }

        /**
         * Convenience method for {@link #CFArrayGetCount} on this object
         *
         * @return The number of values in this array.
         */
        public int getCount() {
            return INSTANCE.CFArrayGetCount(this).intValue();
        }

        /**
         * Convenience method for {@link #CFArrayGetValueAtIndex} on this object
         *
         * @param idx
         *            The index of the value to retrieve.
         * @return The value at the {@code idx} index.

View on GitHub (pinned to d036ad9781)