java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException
ComInterface must define a value for iid
Error message
ComInterface must define a value for iid
What it means
Thrown by ProxyObject's private getIID(ComInterface) helper when the @ComInterface annotation exists but its iid() attribute is null or empty. The IID is mandatory for all proxy operations (QI, advise, unadvise), so an annotation without a GUID is treated as invalid configuration. This is caught during advise/queryInterface flows that do check for the annotation first.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java:519
String formatMessageFromHR = Kernel32Util.formatMessage(hr);
throw new COMException("queryInterface: " + formatMessageFromHR, hr);
}
} catch (RuntimeException e) {
// Do not rewrap COMException
if (e instanceof COMException) {
throw e;
} else {
throw new COMException("Error occured when trying to query for interface " + comInterface.getName(), e);
}
}
}
private IID getIID(ComInterface annotation) {
String iidStr = annotation.iid();
if (null != iidStr && !iidStr.isEmpty()) {
return new IID(iidStr);
} else {
throw new COMException("ComInterface must define a value for iid");
}
}
// --------------------- ProxyObject ---------------------
private String getAccessorName(java.lang.reflect.Method method, ComProperty prop) {
if (prop.name().isEmpty()) {
String methName = method.getName();
if (methName.startsWith("get")) {
return methName.replaceFirst("get", "");
} else {
throw new RuntimeException(
"Property Accessor name must start with 'get', or set the anotation 'name' value");
}
} else {
return prop.name();
}
}View on GitHub (pinned to d036ad9781)
Solutions
- Set a valid GUID in @ComInterface(iid="{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}")
- Validate iid strings with a GUID parser before use in interfaces
- Regenerate the annotation value from the COM type library (oleview / tlbimp output)
Example fix
// before
@ComInterface(iid = "")
interface MyEvents extends IComEventCallbackListener { ... }
// after
@ComInterface(iid = "{D666E0F0-...}")
interface MyEvents extends IComEventCallbackListener { ... } Defensive patterns
Strategy: validation
Validate before calling
ComInterface a = iface.getAnnotation(ComInterface.class); if (a == null || a.iid() == null || a.iid().isEmpty()) throw new IllegalArgumentException("@ComInterface must define non-empty iid on " + iface.getName()); Type guard
boolean hasIid = (Class<?> c) -> c.isAnnotationPresent(ComInterface.class) && !c.getAnnotation(ComInterface.class).iid().isEmpty();
Try / catch
try { proxy.advise(iface, listener); } catch (COMException e) { LOG.error("iid resolution failed", e); } Prevention
- Validate @ComInterface iid values in unit tests (GUID format check)
- Never ship placeholder/empty GUIDs
- Regenerate GUIDs from the type library when it changes
When it happens
Trigger: @ComInterface present with empty iid string, e.g. @ComInterface(iid="") or relying on a default that resolves to empty; annotation processed through a proxy/subclass where iid resolution fails.
Common situations: Copy-pasted annotation where the GUID was deleted; templates with placeholder GUIDs left blank; annotation defined with iid pointing to a constant that failed to initialize.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- advise: Interface must define a value for either iid via the
- ComInterface must define a value for iid
- advise: Interface must define a value for either iid via the
- unadvise: Interface must define a value for iid via the ComI
- queryInterface: Interface must define a value for iid via th
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/7c013c3f5fede302.
Report an issue: GitHub.