Skip to content

JVM does not exit after closing connections when queryTimeout is used #504

@eickeee

Description

@eickeee

What happens?

After closing all connections, the JVM does not exit if a statement query timeout has been set. A non-daemon thread named duckdb-query-cancel-scheduler-thread stays alive and keeps the process running.

To Reproduce

import java.sql.DriverManager

fun main() {
    Class.forName("org.duckdb.DuckDBDriver")
    DriverManager.getConnection("jdbc:duckdb:").use { conn ->
        conn.createStatement().use { stmt ->
            stmt.queryTimeout = 1
            stmt.execute("select 1")
        }
    }
    println("Done (should exit)")
}

Expected

JVM exits after printing Done (should exit).

Observed

Process hangs. Thread dump shows:

"duckdb-query-cancel-scheduler-thread" prio=5 WAITING
  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(...)
  at java.util.concurrent.ThreadPoolExecutor.getTask(...)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(...)
  at java.lang.Thread.run(...)

Environment

  • duckdb_jdbc: 1.4.3.0
  • JDK: 23.0.2
  • OS: macOS

Notes

DuckDBDriver creates the scheduler thread in a static initializer:

ThreadFactory tf = r -> new Thread(r, "duckdb-query-cancel-scheduler-thread");
scheduler = new ScheduledThreadPoolExecutor(1, tf);

The thread is non-daemon and there is no shutdown when connections close.

Workaround: reflectively shut down the scheduler after use. A driver-level fix (daemon thread or explicit shutdown) would be preferable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions