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

advise: Interface must define a value for either iid via the

Error message

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

What it means

Thrown by ProxyObject.advise() when the callback interface class passed in has no @ComInterface annotation. JNA's COM support derives the target IID from the annotation's iid() value; without it the library cannot identify which connection point to advise. This is a programming/configuration error in the callback interface definition, not a runtime COM failure.

Source

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

        // find connection point for comEventCallback interface
        final REFIID adviseRiid = new REFIID(iid.getPointer());
        final PointerByReference ppCp = new PointerByReference();
        HRESULT hr = rawCpc.FindConnectionPoint(adviseRiid, ppCp);
        COMUtils.checkRC(hr);
        final ConnectionPoint rawCp = new ConnectionPoint(ppCp.getValue());
        return rawCp;
    }

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

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

            final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid);

            // create the dispatch listener
            final IDispatchCallback rawListener = factory.createDispatchCallback(comEventCallbackInterface, comEventCallbackListener);
            // store it the comEventCallback argument, so it is not garbage
            // collected.
            comEventCallbackListener.setDispatchCallbackListener(rawListener);
            // set the dispatch listener to listen to events from the connection
            // point
            final DWORDByReference pdwCookie = new DWORDByReference();
            HRESULT hr = rawCp.Advise(rawListener, pdwCookie);
            int n = rawCp.Release(); // release before check in case check
            // throws exception
            COMUtils.checkRC(hr);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Annotate the callback interface with @ComInterface(iid="{GUID}") matching the COM type library
  2. Verify the GUID against the COM object's type library (oleview/IDL)
  3. Ensure you pass the annotated interface class, not a subclass without inherited-visible annotation behavior

Example fix

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

Strategy: validation

Validate before calling

if (!iface.isAnnotationPresent(ComInterface.class)) { throw new IllegalArgumentException(iface.getName() + " lacks @ComInterface(iid)"); }

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling proxy.advise(listenerInterface, listener) where listenerInterface (e.g. a DIID callback interface) lacks @ComInterface(iid="...").

Common situations: Hand-written callback interfaces copied from other wrappers; interfaces where the author relied on name-based lookup that this library does not perform; refactoring that removed the annotation.

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