java-native-access/jna · error · UnsupportedOperationException

immutable reference

Error message

immutable reference

What it means

Some WinNT structure classes offer an immutable mode in which the pointer is fixed at construction; calling setPointer on such an instance throws this UnsupportedOperationException. The design prevents callers from retargeting a reference that must stay bound to its original native memory (typically a const/out-style reference).

Solutions

  1. Create a new mutable instance for each call instead of reusing the immutable one.
  2. If mutability is required, construct the object in non-immutable mode (use the appropriate constructor, not the immutable/constant factory).
  3. Use a plain Pointer/Memory buffer that you own and pass that instead.
  4. Check for accidental writes: guard re-binding behind a copy of the structure.

Example fix

// before
ref.setPointer(newBuffer); // UnsupportedOperationException if immutable
// after
PointerType mutable = new PointerType();
mutable.setPointer(newBuffer);
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure the reference is not immutable before rebinding
// (immutable instances are created via the immutable/constant constructors)

Type guard

static boolean isMutableRef(PointerType p) {
    try {
        p.setPointer(p.getPointer());
        return true;
    } catch (UnsupportedOperationException e) {
        return false;
    }
}

Try / catch

try {
    ref.setPointer(newBuffer);
} catch (UnsupportedOperationException e) {
    ref = new PointerType(); // fresh mutable instance
    ref.setPointer(newBuffer);
}

Prevention

When it happens

Trigger: Calling setPointer (directly, or via structure read/write that assigns pointers) on an immutable instance — e.g. reusing a constant/immutable reference object across multiple native calls or trying to rebind it to a new buffer.

Common situations: Reusing a shared immutable reference as an output parameter across calls; copying field values from one structure into an immutable-typed field; accidentally treating a by-reference constant as a mutable buffer.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/WinNT.java:1393

        public HANDLE(Pointer p) {
            setPointer(p);
            immutable = true;
        }

        /** Override to the appropriate object for INVALID_HANDLE_VALUE. */
        @Override
        public Object fromNative(Object nativeValue, FromNativeContext context) {
            Object o = super.fromNative(nativeValue, context);
            if (WinBase.INVALID_HANDLE_VALUE.equals(o)) {
                return WinBase.INVALID_HANDLE_VALUE;
            }
            return o;
        }

        @Override
        public void setPointer(Pointer p) {
            if (immutable) {
                throw new UnsupportedOperationException("immutable reference");
            }

            super.setPointer(p);
        }

        @Override
        public String toString() {
            return String.valueOf(getPointer());
        }
    }

    /**
     * LPHANDLE
     */
    public static class HANDLEByReference extends ByReference {
        public HANDLEByReference() {
            this(null);
        }

View on GitHub (pinned to d036ad9781)