java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException

queryInterface: Interface must define a value for iid via th

Error message

queryInterface: Interface must define a value for iid via the ComInterface annotation

What it means

Thrown by ProxyObject.queryInterface() when the target interface class has no @ComInterface annotation providing an IID. The library needs the IID to build the REFIID for the underlying IDispatch.QueryInterface call. Without it, the request cannot be formulated.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java:484

        if (argParams.length == 0 || !method.isVarArgs() || !(argParams[argParams.length - 1] instanceof Object[])) {
            return argParams;
        }
        // when last parameter is Object[] -> unfold the ellipsis:
        Object[] varargs = (Object[]) argParams[argParams.length - 1];
        Object[] args = new Object[argParams.length - 1 + varargs.length];
        System.arraycopy(argParams, 0, args, 0, argParams.length - 1);
        System.arraycopy(varargs, 0, args, argParams.length - 1, varargs.length);
        return args;
    }

    @Override
    public <T> T queryInterface(Class<T> comInterface) throws COMException {
        assert COMUtils.comIsInitialized() : "COM not initialized";

        try {
            ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class);
            if (null == comInterfaceAnnotation) {
                throw new COMException(
                        "queryInterface: Interface must define a value for iid via the ComInterface annotation");
            }
            final IID iid = this.getIID(comInterfaceAnnotation);
            final PointerByReference ppvObject = new PointerByReference();

            HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID(iid), ppvObject);

            if (WinNT.S_OK.equals(hr)) {
                Dispatch dispatch = new Dispatch(ppvObject.getValue());
                T t = this.factory.createProxy(comInterface, dispatch);
                // QueryInterface returns a COM object pointer with a +1
                // reference, we must drop one,
                // Note: createProxy adds one;
                int n = dispatch.Release();
                return t;
            } else {
                String formatMessageFromHR = Kernel32Util.formatMessage(hr);
                throw new COMException("queryInterface: " + formatMessageFromHR, hr);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Add @ComInterface(iid="{GUID}") to the interface being queried
  2. Confirm the GUID matches the COM type library entry
  3. Use the interface returned by Factory.createProxy only with properly annotated interfaces

Example fix

// before
Foo foo = proxy.queryInterface(Foo.class); // Foo unannotated
// after
@ComInterface(iid="{12345678-1234-1234-1234-123456789012}")
interface Foo extends IUnknown { ... }
Foo foo = proxy.queryInterface(Foo.class);
Defensive patterns

Strategy: validation

Validate before calling

if (!comInterface.isAnnotationPresent(ComInterface.class)) { throw new IllegalArgumentException(comInterface.getName() + " needs @ComInterface(iid)"); }

Type guard

boolean isQueryable = (Class<?> c) -> c.isAnnotationPresent(ComInterface.class) && c.getAnnotation(ComInterface.class).iid() != null && !c.getAnnotation(ComInterface.class).iid().isEmpty();

Try / catch

try { Foo f = proxy.queryInterface(Foo.class); } catch (COMException e) { LOG.error("QI failed", e); }

Prevention

When it happens

Trigger: Calling proxy.queryInterface(SomeClass.class) where SomeClass is a plain interface without @ComInterface(iid="...").

Common situations: Querying with a helper/utility interface defined ad hoc; forgetting to annotate a new interface added to the codebase; passing java.lang.Cloneable-like generic interfaces by mistake.

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


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/46d90341744c03d2. Report an issue: GitHub.