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

Error occured in unadvise when trying to disconnect the list

Error message

Error occured in unadvise when trying to disconnect the listener from <this>

What it means

Generic wrapper COMException thrown by ProxyObject.unadvise() when disconnecting the listener throws a non-COMException RuntimeException. The original exception is preserved as the cause; the message includes the proxy's toString. Failures here typically mean the connection point or cookie is no longer valid.

Source

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

            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);
            }
        }
    }

    // --------------------- IDispatch ------------------------------
    @Override
    public <T> void setProperty(String name, T value) {
        DISPID dispID = resolveDispId(this.getRawDispatch(), name);
        setProperty(dispID, value);
    }

    @Override
    public <T> void setProperty(DISPID dispId, T value) {
        assert COMUtils.comIsInitialized() : "COM not initialized";

        VARIANT v = Convert.toVariant(value);
        WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYPUT, null, this.getRawDispatch(), dispId, v);
        Convert.free(v, value); // Free value allocated by Convert#toVariant

View on GitHub (pinned to d036ad9781)

Solutions

  1. Check getCause() for the underlying error
  2. Ensure the cookie comes from the matching advise() on the same interface/proxy
  3. Call unadvise exactly once per successful advise
  4. Unadvise before releasing the proxy, on the same thread/apartment

Example fix

// before
proxy.unadvise(MyEvents.class, cookieFromOtherProxy); // fails
// after
IComEventCallbackCookie cookie = proxy.advise(MyEvents.class, listener);
try { /* use */ } finally { proxy.unadvise(MyEvents.class, cookie); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (cookie == null || iface == null) throw new IllegalArgumentException("cookie and interface required");

Type guard

boolean validPair = cookie != null && iface.isAnnotationPresent(ComInterface.class);

Try / catch

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

Prevention

When it happens

Trigger: unadvise() fails while fetching the connection point or calling IConnectionPoint.Unadvise(cookie) — e.g. an invalid/stale cookie, or the COM object already released its connection points.

Common situations: Calling unadvise with a cookie from a different advise call; double-unadvise; unadvising after the COM server terminated; wrong interface class for the cookie.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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