java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException
createObject: Interface must define a value for either clsId
Error message
createObject: Interface must define a value for either clsId or progId via the ComInterface annotation
What it means
ObjectFactory.createObject instantiates a COM object for the given interface; it requires the interface to carry a @ComObject annotation that supplies a clsId or progId. If the annotation is missing entirely, this COMException is thrown. Without the annotation the factory has no way to know which COM class to CoCreateInstance.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java:108
public <T> T createProxy(Class<T> comInterface, IDispatch dispatch) {
assert COMUtils.comIsInitialized() : "COM not initialized";
ProxyObject jop = new ProxyObject(comInterface, dispatch, this);
Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class<?>[]{comInterface}, jop);
T result = comInterface.cast(proxy);
return result;
}
/**
* Creates a new COM object (CoCreateInstance) for the given progId and
* returns a ProxyObject for the given interface.
*/
public <T> T createObject(Class<T> comInterface) {
assert COMUtils.comIsInitialized() : "COM not initialized";
ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class);
if (null == comObectAnnotation) {
throw new COMException(
"createObject: Interface must define a value for either clsId or progId via the ComInterface annotation");
}
final GUID guid = this.discoverClsId(comObectAnnotation);
final PointerByReference ptrDisp = new PointerByReference();
WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(guid, null,
WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp);
COMUtils.checkRC(hr);
Dispatch d = new Dispatch(ptrDisp.getValue());
T t = this.createProxy(comInterface, d);
//CoCreateInstance returns a pointer to COM object with a +1 reference count, so we must drop one
//Note: the createProxy adds one
int n = d.Release();
return t;
}
/**View on GitHub (pinned to d036ad9781)
Solutions
- Annotate the interface with @ComObject(clsId="{GUID}") or @ComObject(progId="Excel.Application")
- Confirm the annotation is com.sun.jna.platform.win32.COM.util.annotation.ComObject (wrong import silently fails lookup)
- Rebuild and verify the class file passed to createObject actually retains the annotation
Example fix
// before
public interface IApplication extends IComObject { ... }
factory.createObject(IApplication.class);
// after
@ComObject(progId = "Excel.Application")
public interface IApplication extends IComObject { ... }
factory.createObject(IApplication.class); Defensive patterns
Strategy: validation
Validate before calling
if (iface.getAnnotation(ComObject.class) == null)
throw new IllegalArgumentException(iface.getName() + " requires @ComObject(clsId|progId)"); Try / catch
try { T obj = factory.createObject(iface); } catch (COMException e) { if (e.getMessage().contains("clsId or progId")) { /* add annotation */ } throw e; } Prevention
- Annotate every creatable COM interface with @ComObject
- Verify the annotation import is the JNA one
- Add a reflection-based test asserting required annotations
When it happens
Trigger: Calling factory.createObject(MyComInterface.class) where MyComInterface has no @ComObject annotation; interface defined against a different annotation (e.g. only @ComInterface); annotation removed in a refactor.
Common situations: Hand-writing the Java COM interface and forgetting @ComObject; migrating code that previously used raw GUIDs/IDispatch to the annotation-based util API; copy-pasting an event-callback interface (which uses @ComInterface) where a creatable class interface is needed.
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
- ComObject must define a value for either clsId or progId
- 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/281a62adb44d3013.
Report an issue: GitHub.