Skip to content

JDBC driver: Closing a Connection does not close its Statement(s), potentially leading to exceptions related to memory leaks #932

@ennuite

Description

@ennuite

Describe the bug, including details regarding any error messages, version, and platform.

According to the JDBC specification 4.3 available at https://download.oracle.com/otn-pub/jcp/jdbc-4_3-mrel3-eval-spec/jdbc4.3-fr-spec.pdf, chapter 9.6.4.1:

All Statement objects created from a given
Connection object will be closed when the close method for the Connection
object is called.

In the Flight SQL JDBC driver closing a Connection does not automatically close the Statement instances obtained via that Connection, making it non compliant with the standard.

Due to this non compliance, on closing a Connection that has a Statement with one or more ResultSet that haven't been fully consumed, we get an exception on Connection.close()

Code to reproduce:

`
try {

  // Establish connection

  Connection connection = DriverManager.getConnection(jdbcUrl, properties);
  System.out.println("Connected to Arrow Flight SQL server");

  Statement stmt = connection.createStatement();
  // my_table needs to have some rows for the bug to manifest itself
  ResultSet rs = stmt.executeQuery("SELECT * FROM my_table");
  // adding this close will eliminate the memory leak, without needing to close the Statement
  // rs.close();

  // with stmt.close() we get no memory leak, even if we didn't close the ResultSet
  //stmt.close();

  connection.close();
  System.out.println("\nConnection closed");

} catch (Exception e) {
  System.err.println("Error: " + e.getMessage());
  e.printStackTrace();
}

`

Resulting in the following exception and stack trace

Dec 14, 2025 5:36:23 PM org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.memory.BaseAllocator close
SEVERE: Memory was leaked by query. Memory leaked: (32)
Allocator(flight-client) 0/32/32/9223372036854775807 (res/actual/peak/limit)

Error: Failed to clean up client resources.
java.sql.SQLException: Failed to clean up client resources.
	at org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.close(ArrowFlightSqlClientHandler.java:269)
	at org.apache.arrow.driver.jdbc.ArrowFlightConnection.close(ArrowFlightConnection.java:178)
	at MemoryLeak.main(MemoryLeak.java:136)
Caused by: java.lang.IllegalStateException: Memory was leaked by query. Memory leaked: (32)
Allocator(flight-client) 0/32/32/9223372036854775807 (res/actual/peak/limit)

	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.memory.BaseAllocator.close(BaseAllocator.java:504)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.FlightClient.close(FlightClient.java:744)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:97)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:75)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.FlightSqlClient.close(FlightSqlClient.java:1137)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:97)
	at org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:75)
	at org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.close(ArrowFlightSqlClientHandler.java:267)
	... 2 more


While a user of the driver with good defensive programming practice would open the ResultSet and/or Statement in a try-with block, the driver should still follow the standard and not produce this Exception.

I believe this bug has been here since the creation of the driver, but I have confirmed that it occurs for both version 17.0.0 and 18.3.0 of the driver.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions