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

Error occured when trying get Unknown Id

Error message

Error occured when trying get Unknown Id 

What it means

This COMException wraps any unexpected RuntimeException raised inside ProxyObject.getUnknownId() while fetching the object's IUnknown id. COMExceptions are rethrown as-is; anything else (e.g. NPE, IllegalStateException) is wrapped with this generic message and the original cause attached. It indicates the id lookup failed for a reason other than a plain failed HRESULT.

Source

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

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

                if (WinNT.S_OK.equals(hr)) {
                    Dispatch dispatch = new Dispatch(ppvObject.getValue());
                    this.unknownId = Pointer.nativeValue(dispatch.getPointer());
                    // QueryInterface returns a COM object pointer with a +1
                    // reference, we must drop one,
                    // Note: createProxy adds one;
                    int n = dispatch.Release();
                } else {
                    String formatMessageFromHR = Kernel32Util.formatMessage(hr);
                    throw new COMException("getUnknownId: " + formatMessageFromHR, hr);
                }
            } catch (RuntimeException e) {
                // Do not rewrap COMException
                if (e instanceof COMException) {
                    throw e;
                } else {
                    throw new COMException("Error occured when trying get Unknown Id ", e);
                }
            }
        }
        return this.unknownId;
    }

    @Override
    protected void finalize() throws Throwable {
        this.dispose();
        super.finalize();
    }

    public synchronized void dispose() {
        if (((Dispatch) this.rawDispatch).getPointer() != Pointer.NULL) {
            this.rawDispatch.Release();
            ((Dispatch) this.rawDispatch).setPointer(Pointer.NULL);
            factory.unregister(this);
        }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Inspect getCause() of the thrown COMException to find the real RuntimeException
  2. Verify the proxy has not been disposed/released before calling methods that need the unknown id
  3. Use the proxy only from the thread/apartment that created it
  4. Catch COMException and log the full stack trace including the cause

Example fix

// before
proxy.getIdentifer(); // after dispose -> generic wrapper
// after
Factory factory = new Factory(COMUtils.getCurrentCOM()) { ... };
// keep factory/dispatch alive while using proxy; call HandlerUtil helpers
Defensive patterns

Strategy: try-catch

Validate before calling

if (!COMUtils.comIsInitialized()) { throw new IllegalStateException("COM not initialized"); }

Type guard

boolean alive = handler != null && handler.getObject() != null;

Try / catch

try { ... } catch (COMException e) { Throwable c = e.getCause(); LOG.error("getUnknownId wrapper failed", c); }

Prevention

When it happens

Trigger: A RuntimeException such as NullPointerException or IllegalStateException occurs during getUnknownId() — e.g. the internal dispatch field is null because the proxy was disposed, or QueryInterface threw an unexpected runtime error.

Common situations: Using a proxy after unadvise/dispose lifecycle teardown; proxy created in one thread and disposed in another; NPE from annotation lookups on a malformed interface class.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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