java-native-access/jna · error · java.lang.RuntimeException

ComThread executor has a problem.

Error message

ComThread executor has a problem.

What it means

ComThread wraps a single dedicated COM-initialized thread in an ExecutorService. When the thread factory's newThread is invoked while requiresInitialisation is false, it concludes the executor is being re-created in a broken state and throws this RuntimeException. It signals an internal lifecycle invariant violation of the ComThread object, typically after terminate() or a failed initialisation.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java:79

                    // a message loop see -
                    // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm]
                    // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understanding-COM-Apartments-Part-II.htm]
                    WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, coinitialiseExFlag);
                    isCOMThread.set(true);
                    COMUtils.checkRC(hr);
                    ComThread.this.requiresInitialisation = false;
                } catch (Throwable t) {
                    ComThread.this.uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t);
                }
            }
        };
        executor = Executors.newSingleThreadExecutor(new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                if (!ComThread.this.requiresInitialisation) {
                    // something has gone wrong!
                    throw new RuntimeException("ComThread executor has a problem.");
                }
                Thread thread = new Thread(r, threadName);
                //make sure this is a daemon thread, or it will stop JVM existing
                // if program does not call terminate();
                thread.setDaemon(true);

                thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                    @Override
                    public void uncaughtException(Thread t, Throwable e) {
                        ComThread.this.requiresInitialisation = true;
                        ComThread.this.uncaughtExceptionHandler.uncaughtException(t, e);
                    }
                });

                return thread;
            }
        });

View on GitHub (pinned to d036ad9781)

Solutions

  1. Never reuse a ComThread after terminate(); create a fresh ComThread for a new COM apartment
  2. Ensure all tasks complete before calling terminate() and no tasks are submitted afterwards
  3. Synchronize access so run() is not invoked concurrently with or after terminate()
  4. If this appears without reuse, report it as a JNA bug with a reproducer

Example fix

// before
comThread.terminate();
comThread.run(task); // boom: executor has a problem
// after
comThread.terminate();
ComThread newThread = new ComThread();
newThread.run(task);
Defensive patterns

Strategy: try-catch

Validate before calling

if (comThread == null || terminated) throw new IllegalStateException("ComThread no longer usable; create a new one");

Try / catch

try { comThread.run(task); } catch (RuntimeException e) { if (e.getMessage().contains("executor has a problem")) { comThread = new ComThread(); comThread.run(task); } }

Prevention

When it happens

Trigger: Reusing a ComThread instance after terminate() was called (executor shutdown triggers factory re-entry with stale state); constructing the executor twice on the same ComThread instance; concurrent use of ComThread from multiple threads racing on the requiresInitialisation flag.

Common situations: Calling terminate() then attempting to run another task on the same ComThread instead of creating a new one; application shutdown hooks racing with remaining submitted tasks; framework code (e.g. Spring bean destruction) closing ComThread while work is still queued.

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/8f137e67d438eaad. Report an issue: GitHub.