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
CallbackProxy.createRIID resolves the IID of a COM event callback interface by reading its @ComInterface annotation; if the annotation is absent it throws this COMException. The proxy needs the interface's GUID (IID) to Advise/Unadvise event sinks and cannot proceed without it.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java:92
this.factory = factory;
this.comEventCallbackInterface = comEventCallbackInterface;
this.comEventCallbackListener = comEventCallbackListener;
this.listenedToRiid = this.createRIID(comEventCallbackInterface);
this.dsipIdMap = this.createDispIdMap(comEventCallbackInterface);
this.dispatchListener = new DispatchListener(this);
}
ObjectFactory factory;
Class<?> comEventCallbackInterface;
IComEventCallbackListener comEventCallbackListener;
REFIID listenedToRiid;
public DispatchListener dispatchListener;
Map<DISPID, Method> dsipIdMap;
private REFIID createRIID(Class<?> comEventCallbackInterface) {
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");
}
String iidStr = comInterfaceAnnotation.iid();
if (null == iidStr || iidStr.isEmpty()) {
throw new COMException("ComInterface must define a value for iid");
}
return new REFIID(new IID(iidStr).getPointer());
}
@SuppressWarnings("deprecation") // ComEventCallback is used here to be backwards compatible
private Map<DISPID, Method> createDispIdMap(Class<?> comEventCallbackInterface) {
Map<DISPID, Method> map = new HashMap<>();
for (Method meth : comEventCallbackInterface.getMethods()) {
ComEventCallback callbackAnnotation = meth.getAnnotation(ComEventCallback.class);
ComMethod methodAnnotation = meth.getAnnotation(ComMethod.class);
if (methodAnnotation != null) {
int dispId = methodAnnotation.dispId();View on GitHub (pinned to d036ad9781)
Solutions
- Annotate the event callback interface with @ComInterface(iid="{GUID}")
- Ensure the correct guid attribute (iid) is present, matching the type library
- Rebuild so the annotation is actually compiled onto the interface passed to advise
- If the interface already has @ComObject (for createObject), note advise needs @ComInterface instead
Example fix
// before
public interface IDocumentEvents extends IComEventCallbackListener { ... }
// after
@ComInterface(iid = "{A3B2C1D0-1234-5678-9ABC-DEF012345678}")
public interface IDocumentEvents extends IComEventCallbackListener { ... } Defensive patterns
Strategy: validation
Validate before calling
if (iface.getAnnotation(ComInterface.class) == null)
throw new IllegalArgumentException(iface.getName() + " needs @ComInterface before advising events"); Try / catch
try { factory.addEventListener(iface, method, listener); } catch (COMException e) { if (e.getMessage().contains("ComInterface annotation")) { /* fix annotation */ } } Prevention
- Always pair event callback interfaces with @ComInterface(iid=...)
- Check annotations when migrating event interfaces between APIs
- Unit-test interface setup before touching live COM
When it happens
Trigger: Passing a callback interface (annotated only with @ComEventCallback or none at all, not @ComInterface) to ObjectFactory.addEventListener / CallbackProxy construction; renaming or deleting the @ComInterface annotation during refactoring.
Common situations: Hand-writing a COM event interface and forgetting the annotation; moving an interface between packages so an annotation import is lost; migrating from the deprecated ComEventCallback style to the annotation-based util API.
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
- ComInterface must define a value for iid
- Class type <paramTypes[i].getName()> not mapped to primitive
- createObject: Interface must define a value for either clsId
- ComObject must define a value for either clsId or progId
- advise: Interface must define a value for either iid via the
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/b11ccd99dbdfab03.
Report an issue: GitHub.