java-native-access/jna · error · java.lang.UnsupportedOperationException

remove

Error message

remove

What it means

EnumMoniker's iterator over the running-object-table monikers does not implement element removal; calling Iterator.remove() throws UnsupportedOperationException with the message 'remove'. The enumeration is read-only by design because the underlying IEnumMoniker does not support safe removal through this wrapper.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java:127

                // moniker.getPointer(), ppszDisplayName);
                // COMUtils.checkRC(hr);
                // String name = ppszDisplayName.getString();
                // Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0));
                // TODO: Can we assume that the object is an
                // IDispatch ?
                // Unknown unk = new
                // Unknown(ppunkObject.getValue());
                Dispatch dispatch = new Dispatch(ppunkObject.getValue());
                EnumMoniker.this.cacheNext();
                IDispatch d = EnumMoniker.this.factory.createProxy(IDispatch.class, dispatch);
                //must release a COM Ref, GetObject returns a pointer with +1
                int n = dispatch.Release();
                return d;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("remove");
            }

        };
    }

}

View on GitHub (pinned to d036ad9781)

Solutions

  1. Do not call remove() on this iterator; only iterate
  2. Filter the results into your own collection and manipulate that instead
  3. Release/unregister monikers via the appropriate ROT/COM API (IRunningObjectTable.Revoke) if removal is truly required

Example fix

// before
for (Iterator<?> it = enumMoniker.iterator(); it.hasNext();) {
    Object m = it.next();
    if (isStale(m)) it.remove(); // UnsupportedOperationException
}
// after
List<?> stale = new ArrayList<>();
for (Object m : enumMoniker) {
    if (isStale(m)) stale.add(m);
}
// revoke stale monikers via IRunningObjectTable.Revoke instead
Defensive patterns

Strategy: type-guard

Type guard

static boolean supportsRemove(Iterator<?> it) {
    // EnumMoniker's iterator is read-only; guard before calling remove()
    try { it.remove(); return true; } catch (UnsupportedOperationException e) { return false; }
}

Try / catch

try { it.remove(); } catch (UnsupportedOperationException e) { /* collect and handle removal via ROT Revoke instead */ }

Prevention

When it happens

Trigger: Calling iterator.remove() (directly or via e.g. collection.removeIf or a loop removing entries) while iterating the EnumMoniker list of ROT monikers.

Common situations: Trying to clean up stale entries in the Running Object Table by removing them from the Java iterator; generic code that always calls remove() after filtering; assuming the Java iterator mirrors mutable collection semantics.

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