java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException
ComObject must define a value for either clsId or progId
Error message
ComObject must define a value for either clsId or progId
What it means
ObjectFactory.discoverClsId resolves a GUID from the @ComObject annotation: if clsId is present it is parsed directly, else progId is converted via CLSIDFromProgID. If neither is set, this COMException is thrown. It means the annotation exists but is empty of identifying information.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java:168
return t;
}
GUID discoverClsId(ComObject annotation) {
assert COMUtils.comIsInitialized() : "COM not initialized";
String clsIdStr = annotation.clsId();
final String progIdStr = annotation.progId();
if (null != clsIdStr && !clsIdStr.isEmpty()) {
return new CLSID(clsIdStr);
} else if (null != progIdStr && !progIdStr.isEmpty()) {
final CLSID.ByReference rclsid = new CLSID.ByReference();
WinNT.HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid);
COMUtils.checkRC(hr);
return rclsid;
} else {
throw new COMException("ComObject must define a value for either clsId or progId");
}
}
IDispatchCallback createDispatchCallback(Class<?> comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) {
return new CallbackProxy(this, comEventCallbackInterface, comEventCallbackListener);
}
// Proxy object release their COM interface reference latest in the
// finalize method, which is run when garbadge collection removes the
// object.
// When the factory is finished, the referenced objects loose their
// environment and can't be used anymore. registeredObjects is used
// to dispose interfaces even if garbadge collection has not yet collected
// the proxy objects.
private final List<WeakReference<ProxyObject>> registeredObjects = new LinkedList<>();
public void register(ProxyObject proxyObject) {
synchronized (this.registeredObjects) {View on GitHub (pinned to d036ad9781)
Solutions
- Set exactly one of @ComObject(clsId="{GUID}") or @ComObject(progId="App.Object")
- Prefer progId for readable code, or clsId for precision; verify the value exists on the target machine (progId resolution happens via CLSIDFromProgID)
- Validate the clsId GUID format if using clsId
Example fix
// before
@ComObject
public interface IWorksheet extends IUnknown { ... }
// after
@ComObject(clsId = "{00020820-0000-0000-C000-000000000046}")
public interface IWorksheet extends IUnknown { ... } Defensive patterns
Strategy: validation
Validate before calling
ComObject a = iface.getAnnotation(ComObject.class);
if (a == null || (a.clsId().isEmpty() && a.progId().isEmpty()))
throw new IllegalArgumentException(iface.getName() + " must set clsId or progId"); Try / catch
try { T obj = factory.createObject(iface); } catch (COMException e) { if (e.getMessage().contains("must define a value")) { /* set clsId/progId */ } throw e; } Prevention
- Always fill exactly one of clsId/progId in @ComObject
- Validate GUID format for clsId at startup
- Review generated interfaces for blank annotation attributes
When it happens
Trigger: Declaring @ComObject with neither clsId nor progId attributes; annotation attributes left as empty strings after removing a placeholder; a helper passing a partially populated annotation instance.
Common situations: Copying annotation boilerplate and deleting both attribute values; generating interfaces from a tool that left the fields blank; typos in attribute names so neither recognized field is actually set.
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
- createObject: Interface must define a value for either clsId
- advise: Interface must define a value for either iid via the
- ComInterface must define a value for iid
- Property Accessor name must start with 'get', or set the ano
- Property Mutator name must start with 'set', or set the anot
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/75816fa0f83c5699.
Report an issue: GitHub.