{"record":{"id":"0471b54d98c49234","repo":"java-native-access/jna","slug":"advise-interface-must-define-a-value-for-either-iid-via-the-0471b5","errorCode":null,"errorMessage":"advise: Interface must define a value for either iid via the ComInterface annotation","messagePattern":"advise: Interface must define a value for either iid via the ComInterface annotation","errorType":"exception","errorClass":"com.sun.jna.platform.win32.COM.COMException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java","lineNumber":293,"sourceCode":"        // find connection point for comEventCallback interface\n        final REFIID adviseRiid = new REFIID(iid.getPointer());\n        final PointerByReference ppCp = new PointerByReference();\n        HRESULT hr = rawCpc.FindConnectionPoint(adviseRiid, ppCp);\n        COMUtils.checkRC(hr);\n        final ConnectionPoint rawCp = new ConnectionPoint(ppCp.getValue());\n        return rawCp;\n    }\n\n    @Override\n    public IComEventCallbackCookie advise(Class<?> comEventCallbackInterface,\n            final IComEventCallbackListener comEventCallbackListener)\n            throws COMException {\n        assert COMUtils.comIsInitialized() : \"COM not initialized\";\n\n        try {\n            ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class);\n            if (null == comInterfaceAnnotation) {\n                throw new COMException(\n                        \"advise: Interface must define a value for either iid via the ComInterface annotation\");\n            }\n            final IID iid = this.getIID(comInterfaceAnnotation);\n\n            final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid);\n\n            // create the dispatch listener\n            final IDispatchCallback rawListener = factory.createDispatchCallback(comEventCallbackInterface, comEventCallbackListener);\n            // store it the comEventCallback argument, so it is not garbage\n            // collected.\n            comEventCallbackListener.setDispatchCallbackListener(rawListener);\n            // set the dispatch listener to listen to events from the connection\n            // point\n            final DWORDByReference pdwCookie = new DWORDByReference();\n            HRESULT hr = rawCp.Advise(rawListener, pdwCookie);\n            int n = rawCp.Release(); // release before check in case check\n            // throws exception\n            COMUtils.checkRC(hr);","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java#L275-L311","documentation":"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.","triggerScenarios":"Calling proxy.advise(listenerInterface, listener) where listenerInterface (e.g. a DIID callback interface) lacks @ComInterface(iid=\"...\").","commonSituations":"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.","solutions":["Annotate the callback interface with @ComInterface(iid=\"{GUID}\") matching the COM type library","Verify the GUID against the COM object's type library (oleview/IDL)","Ensure you pass the annotated interface class, not a subclass without inherited-visible annotation behavior"],"exampleFix":"// before\ninterface MyEvents extends IComEventCallbackListener { ... }\nproxy.advise(MyEvents.class, listener);\n// after\n@ComInterface(iid=\"{00020902-0000-0000-C000-000000000046}\")\ninterface MyEvents extends IComEventCallbackListener { ... }\nproxy.advise(MyEvents.class, listener);","handlingStrategy":"validation","validationCode":"if (!iface.isAnnotationPresent(ComInterface.class)) { throw new IllegalArgumentException(iface.getName() + \" lacks @ComInterface(iid)\"); }","typeGuard":"boolean isComInterface = (Class<?> c) -> c.isAnnotationPresent(ComInterface.class);","tryCatchPattern":"try { proxy.advise(iface, listener); } catch (COMException e) { LOG.error(\"advise failed\", e); }","preventionTips":["Require @ComInterface(iid=...) on every event interface","Verify GUIDs against the type library at build time","Use a unit test reflecting over all callback interfaces"],"tags":["com","annotation","config","iid"],"backgroundTag":"missing-required-config-field","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}