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
- Create a new mutable instance for each call instead of reusing the immutable one.
- If mutability is required, construct the object in non-immutable mode (use the appropriate constructor, not the immutable/constant factory).
- Use a plain Pointer/Memory buffer that you own and pass that instead.
- 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
- Never reuse immutable reference objects as out-parameters.
- Create a new instance per native call when rebinding is needed.
- Check the constructor used — constant/immutable factories yield read-only references.
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
- Could not set proxy blanket.
- DACL is invalid
- destDir must be a directory.
- Error loading DLLCallback class
- Expected GetTokenInformation to fail with…
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)