{"record":{"id":"281a62adb44d3013","repo":"java-native-access/jna","slug":"createobject-interface-must-define-a-value-for-either-clsid","errorCode":null,"errorMessage":"createObject: Interface must define a value for either clsId or progId via the ComInterface annotation","messagePattern":"createObject: Interface must define a value for either clsId or progId 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/ObjectFactory.java","lineNumber":108,"sourceCode":"    public <T> T createProxy(Class<T> comInterface, IDispatch dispatch) {\n        assert COMUtils.comIsInitialized() : \"COM not initialized\";\n\n        ProxyObject jop = new ProxyObject(comInterface, dispatch, this);\n        Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class<?>[]{comInterface}, jop);\n        T result = comInterface.cast(proxy);\n        return result;\n    }\n\n    /**\n     * Creates a new COM object (CoCreateInstance) for the given progId and\n     * returns a ProxyObject for the given interface.\n     */\n    public <T> T createObject(Class<T> comInterface) {\n        assert COMUtils.comIsInitialized() : \"COM not initialized\";\n\n        ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class);\n        if (null == comObectAnnotation) {\n            throw new COMException(\n                \"createObject: Interface must define a value for either clsId or progId via the ComInterface annotation\");\n        }\n        final GUID guid = this.discoverClsId(comObectAnnotation);\n\n        final PointerByReference ptrDisp = new PointerByReference();\n        WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(guid, null,\n            WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp);\n\n        COMUtils.checkRC(hr);\n        Dispatch d = new Dispatch(ptrDisp.getValue());\n        T t = this.createProxy(comInterface, d);\n        //CoCreateInstance returns a pointer to COM object with a +1 reference count, so we must drop one\n        //Note: the createProxy adds one\n        int n = d.Release();\n        return t;\n    }\n\n    /**","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java#L90-L126","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\npublic interface IApplication extends IComObject { ... }\nfactory.createObject(IApplication.class);\n// after\n@ComObject(progId = \"Excel.Application\")\npublic interface IApplication extends IComObject { ... }\nfactory.createObject(IApplication.class);","handlingStrategy":"validation","validationCode":"if (iface.getAnnotation(ComObject.class) == null)\n    throw new IllegalArgumentException(iface.getName() + \" requires @ComObject(clsId|progId)\");","typeGuard":null,"tryCatchPattern":"try { T obj = factory.createObject(iface); } catch (COMException e) { if (e.getMessage().contains(\"clsId or progId\")) { /* add annotation */ } throw e; }","preventionTips":["Annotate every creatable COM interface with @ComObject","Verify the annotation import is the JNA one","Add a reflection-based test asserting required annotations"],"tags":["java","com","annotation","createobject","clsid"],"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"}