apache / apache/arrow-java

[Java] Invocation of close method from ArrowFlightConnection throws a SQLException when using catalog as parameter

Đang mở
#66 5 bình luận 0 reaction 1 người được giao Được @scruz-denodo nhận Xem trên GitHub
help wanted Type: bug
Ngôn ngữ chính
Java
Star
94
Fork
152
Merge trung bình
3 ngày 16 giờ
Pull request đã merge (30 ngày)
11

Mô tả

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

**Affected version**
flight-sql-jdbc-driver version 17.0.0

**Description**

With flight-sql-jdbc-driver version 17 the method `org.apache.arrow.driver.jdbc.ArrowFlightConnection#close` returns a SQLException when the connection has defined a value for `catalog` parameter.

I was testing this change and I am facing a problem when the `java.sql.Connection#close` method of the JDBC connection is called.

I am receiving the following error invoking the method.

```
Exception in thread "main" java.sql.SQLException: UNKNOWN: Uncaught exception in the SynchronizationContext. Re-thrown.
at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
at org.apache.arrow.driver.jdbc.ArrowFlightConnection.close(ArrowFlightConnection.java:187)
at com.arrowflight.test.Main.test7(Main.java:249)
at com.arrowflight.test.Main.main(Main.java:27)
Caused by: io.grpc.StatusRuntimeException: UNKNOWN: Uncaught exception in the SynchronizationContext. Re-thrown.
at io.grpc.Status.asRuntimeException(Status.java:525)
at io.grpc.internal.RetriableStream$1.uncaughtException(RetriableStream.java:75)
at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:96)
at io.grpc.SynchronizationContext.execute(SynchronizationContext.java:126)
at io.grpc.internal.RetriableStream.safeCloseMasterListener(RetriableStream.java:838)
at io.grpc.internal.RetriableStream.cancel(RetriableStream.java:531)
at io.grpc.internal.RetriableStream.start(RetriableStream.java:393)
at io.grpc.internal.ClientCallImpl.startInternal(ClientCallImpl.java:285)
at io.grpc.internal.ClientCallImpl.start(ClientCallImpl.java:184)
at io.grpc.ForwardingClientCall.start(ForwardingClientCall.java:32)
at org.apache.arrow.flight.grpc.ClientInterceptorAdapter$FlightClientCall.start(ClientInterceptorAdapter.java:142)
at io.grpc.ForwardingClientCall.start(ForwardingClientCall.java:32)
at io.grpc.stub.MetadataUtils$HeaderAttachingClientInterceptor$HeaderAttachingClientCall.start(MetadataUtils.java:75)
at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:335)
at io.grpc.stub.ClientCalls.asyncUnaryRequestCall(ClientCalls.java:311)
at io.grpc.stub.ClientCalls.blockingServerStreamingCall(ClientCalls.java:210)
at org.apache.arrow.flight.impl.FlightServiceGrpc$FlightServiceBlockingStub.doAction(FlightServiceGrpc.java:874)
at org.apache.arrow.flight.FlightClient.doAction(FlightClient.java:168)
at org.apache.arrow.flight.FlightClient.closeSession(FlightClient.java:686)
at org.apache.arrow.flight.sql.FlightSqlClient.closeSession(FlightSqlClient.java:998)
at org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.close(ArrowFlightSqlClientHandler.java:224)
at org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:97)
at org.apache.arrow.util.AutoCloseables.close(AutoCloseables.java:75)
at org.apache.arrow.driver.jdbc.ArrowFlightConnection.close(ArrowFlightConnection.java:181)
... 2 more
Caused by: java.util.concurrent.RejectedExecutionException: Task io.grpc.internal.SerializingExecutor@6ecdbab8 rejected from java.util.concurrent.ThreadPoolExecutor@3dd4a6fa[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 25]
at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2055)
at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:825)
at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1355)
at io.grpc.internal.SerializingExecutor.schedule(SerializingExecutor.java:102)
at io.grpc.internal.SerializingExecutor.execute(SerializingExecutor.java:95)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.closedInternal(ClientCallImpl.java:736)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.closed(ClientCallImpl.java:680)
at io.grpc.internal.RetriableStream$4.run(RetriableStream.java:843)
at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:94)
... 23 more
```

I think the reason is the following. Checking this code:

https://github.com/apache/arrow/blob/6a2e19a852b367c72d7b12da4d104456491ed8b7/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightConnection.java#L174-L189

- `close` method invokes `clientHandler.close();` at line 175. Here is where now is invoked the `closeSession` method at line 224.
https://github.com/apache/arrow/blob/6a2e19a852b367c72d7b12da4d104456491ed8b7/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java#L222-L225
- after that again on `ArrowFlightConnection.java`, the `executorService` is closed at like 177
- and the `clientHandler.close();` is called again at line 181.
- with this call, the `closeSession` method is invoked again. And it is here when the exception is thrown. Because the executorService was already shutdown.

https://github.com/apache/arrow/blob/6a2e19a852b367c72d7b12da4d104456491ed8b7/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightConnection.java#L174-L189

I think that line line 181 `from org.apache.arrow.driver.jdbc.ArrowFlightConnection#close` should be remove for avoding the problem. The close is already done at 175.

Also, I would remove the is if:
https://github.com/apache/arrow/blob/6a2e19a852b367c72d7b12da4d104456491ed8b7/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java#L222-L225
why not invoking the `closeSession` when the catalog was not set?

It can be reproducible with this code:
```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

public class CloseIssue {
private static final String URL = "jdbc:arrow-flight-sql://localhost:9994?catalog=mydatabase&useEncryption=0";

public static void main(String[] args) throws Exception {
Class.forName("org.apache.arrow.driver.jdbc.ArrowFlightJdbcDriver");
try (Connection conn = DriverManager.getConnection(URL, "admin", "admin")) {
try (PreparedStatement pst = conn.prepareStatement("select 1");
ResultSet rs = pst.executeQuery()) {
ResultSetMetaData rsm = rs.getMetaData();
for (int i = 1; i <= rsm.getColumnCount(); i++) {
System.out.print(rsm.getColumnName(i) + " (" + rsm.getColumnType(i) + ") ");
}
}
}
}
}
```

This problems **does not happen with prior versions**, so it can be considered a regression.

### Component(s)

Java

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.