java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException

unadvise: Interface must define a value for iid via the ComI

Error message

unadvise: Interface must define a value for iid via the ComInterface annotation

What it means

Thrown by ProxyObject.unadvise() when the event callback interface class lacks a @ComInterface annotation from which the IID can be read. Without the IID the library cannot locate the connection point from which to disconnect the cookie. Like the advise counterpart, it is a definition error in the interface class.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java:333

        } catch (RuntimeException e) {
            // Do not rewrap COMException
            if (e instanceof COMException) {
                throw e;
            } else {
                throw new COMException("Error occured in advise when trying to connect the listener " + comEventCallbackListener, e);
            }
        }
    }

    @Override
    public void unadvise(Class<?> comEventCallbackInterface, final IComEventCallbackCookie cookie) throws COMException {
        assert COMUtils.comIsInitialized() : "COM not initialized";

        try {
            ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class);
            if (null == comInterfaceAnnotation) {
                throw new COMException(
                        "unadvise: Interface must define a value for iid via the ComInterface annotation");
            }
            IID iid = this.getIID(comInterfaceAnnotation);

            final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid);

            HRESULT hr = rawCp.Unadvise(((ComEventCallbackCookie) cookie).getValue());

            rawCp.Release();
            COMUtils.checkRC(hr);

        } catch (RuntimeException e) {
            // Do not rewrap COMException
            if (e instanceof COMException) {
                throw e;
            } else {
                throw new COMException("Error occured in unadvise when trying to disconnect the listener from " + this, e);
            }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Annotate the interface with @ComInterface(iid="{GUID}") exactly as used in advise
  2. Pass the same interface class used in the original advise() call
  3. Store the interface class and cookie together so unadvise uses matching values

Example fix

// before
proxy.unadvise(UnannotatedEvents.class, cookie);
// after
@ComInterface(iid="{00020902-0000-0000-C000-000000000046}")
interface MyEvents extends IComEventCallbackListener { ... }
proxy.unadvise(MyEvents.class, cookie);
Defensive patterns

Strategy: validation

Validate before calling

if (!iface.isAnnotationPresent(ComInterface.class)) { throw new IllegalArgumentException("unadvise requires @ComInterface annotation"); }

Type guard

boolean canUnadvise = (Class<?> c) -> c.isAnnotationPresent(ComInterface.class);

Try / catch

try { proxy.unadvise(iface, cookie); } catch (COMException e) { LOG.error("unadvise failed", e); }

Prevention

When it happens

Trigger: Calling proxy.unadvise(listenerInterface, cookie) where listenerInterface has no @ComInterface annotation or an empty iid.

Common situations: unadvise called with a different (unannotated) interface class than the one used for advise; annotation removed during refactoring; using a generated subclass.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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