apache / arrow-java

Official Java implementation of Apache Arrow
https://arrow.apache.org/
Apache License 2.0
4 stars 4 forks source link

[Java] java.lang.NullPointerException: null at org.apache.arrow.driver.jdbc. Failed in getDialectProperties #159

Open YuriyGavrilov opened 1 year ago

YuriyGavrilov commented 1 year ago

Describe the enhancement requested

There is an error with jdbc arrow driver in Tableau. Hope somebody find solution to fix it. or maybe addd necessary dialect to arrow

2023-10-12 23:06:37.332 +0300 (,,,,3,23) grpc-default-executor-3 : ERROR com.tableau.connect.util.GrpcServiceHelper - Failed in getDialectProperties.
java.lang.NullPointerException: null
    at org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.getSqlInfoEnumOptionAndCacheIfCacheIsEmpty(ArrowDatabaseMetadata.java:758) ~[?:?]
    at org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.supportsANSI92EntryLevelSQL(ArrowDatabaseMetadata.java:343) ~[?:?]
    at com.tableausoftware.jdbc.JDBCProtocolImpl.getSQL92Level(JDBCProtocolImpl.java:1038) ~[jdbcserver.jar:20232.0.5]
    at com.tableausoftware.jdbc.JDBCProtocolImpl.getDialectPropertiesImpl(JDBCProtocolImpl.java:1168) ~[jdbcserver.jar:20232.0.5]
    at com.tableausoftware.jdbc.JDBCProtocolImpl.getDialectProperties(JDBCProtocolImpl.java:1189) ~[jdbcserver.jar:20232.0.5]
    at com.tableau.connect.service.ProtocolService.getDialectProperties(ProtocolService.java:260) ~[jdbcserver.jar:20232.0.5]
    at com.tableau.connect.grpc.GrpcProtocolService.lambda$getDialectProperties$15(GrpcProtocolService.java:220) ~[jdbcserver.jar:20232.0.5]
    at com.tableau.connect.grpc.GrpcProtocolService.wrap(GrpcProtocolService.java:280) ~[jdbcserver.jar:20232.0.5]
    at com.tableau.connect.grpc.GrpcProtocolService.getDialectProperties(GrpcProtocolService.java:219) ~[jdbcserver.jar:20232.0.5]
    at com.tableau.connect.generated.ProtocolServiceGrpc$MethodHandlers.invoke(ProtocolServiceGrpc.java:1536) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.stub.ServerCalls$UnaryServerCallHandler$UnaryServerCallListener.onHalfClose(ServerCalls.java:182) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.PartialForwardingServerCallListener.onHalfClose(PartialForwardingServerCallListener.java:35) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.ForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:23) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.ForwardingServerCallListener$SimpleForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:40) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.Contexts$ContextualizedServerCallListener.onHalfClose(Contexts.java:86) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.halfClosed(ServerCallImpl.java:354) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed.runInContext(ServerImpl.java:866) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) ~[jdbcserver.jar:20232.0.5]
    at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133) ~[jdbcserver.jar:20232.0.5]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
    at java.lang.Thread.run(Unknown Source) ~[?:?]
2023-10-12 23:06:37.332 +0300 (,,,,3,23) grpc-default-executor-3 : INFO  com.tableau.connect.grpc.GrpcProtocolService - End local request 23 /getDialectProperties.
2023-10-12 23:06:37.334 +0300 (,,,,3,24) grpc-default-executor-3 : INFO  com.tableau.connect.grpc.GrpcProtocolService - Start local request 24 /isConnected.
2023-10-12 23:06:37.334 +0300 (,,,,3,24) grpc-default-executor-3 : INFO  com.tableau.connect.grpc.GrpcProtocolService - End local request 24 /isConnected.
2023-10-12 23:06:37.335 +0300 (,,,,3,25) grpc-default-executor-3 : INFO  com.tableau.connect.grpc.GrpcProtocolService - Start local request 25 /closeProtocol.
2023-10-12 23:06:37.335 +0300 (,,,,3,25) grpc-default-executor-3 : INFO  com.tableausoftware.jdbc.JDBCProtocolImpl - Closing connection 3.
2023-10-12 23:06:37.337 +0300 (,,,,3,25) grpc-default-executor-3 : INFO  com.tableau.connect.grpc.GrpcProtocolService - End local request 25 /closeProtocol.

There are also some warning messeges at cfjd.io.netty.util.internal.ReflectionUtil

WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
2023-10-12T21:59:50.037127 Protocol Server starting. 
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by cfjd.io.netty.util.internal.ReflectionUtil (file:/Users/yuriygavrilov/Library/Tableau/Drivers/flight-sql-jdbc-driver-13.0.0.jar) to constructor java.nio.DirectByteBuffer(long,int)
WARNING: Please consider reporting this to the maintainers of cfjd.io.netty.util.internal.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Component(s)

Java

To reproduce this error try to start arrow server with:

docker run --name flight-sql \
           --detach \
           --rm \
           --tty \
           --init \
           --publish 31337:31337 \
           --env FLIGHT_PASSWORD="flight_password" \
           --pull missing \
           --mount type=bind,source=$(pwd),target=/opt/flight_sql/data \
           --env DATABASE_FILE_NAME="tpch_sf1.duckdb" \
           voltrondata/flight-sql:latest

Add jdbc driver to tableau driver from https://repo.maven.apache.org/maven2/org/apache/arrow/arrow-jdbc/13.0.0/ to local folder like /Users/{user}/Library/Tableau/Drivers/flight-sql-jdbc-driver-13.0.0.jar

Try to connect with this URL jdbc:arrow-flight-sql://localhost:31337?useEncryption=true&user=flight_username&password=flight_password&disableCertificateVerification=true

This works fine in dbeaver ...

Снимок экрана 2023-10-13 в 00 26 51
jduo commented 1 year ago

I can't reproduce this locally @YuriyGavrilov . However I do see a multi-threading bug in the code that populates getSqlInfo() properties: https://github.com/apache/arrow/blob/563078fb70f7d23e716a2c1c79e96f7409c02f3f/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowDatabaseMetadata.java#L732

The checking of if this cache is populated isn't thread-safe. If one thread starts populating the cache, and another thread tries to access a property, the second thread will see the cache is non-empty and think all properties have been cached rather than waiting for the rest of the cache to fill.

jduo commented 1 year ago

@YuriyGavrilov , the thread-safety issue mentioned above is now fixed. It'd be great if you could retry the driver in Tableau with this fix in place (and close this issue if it is working consistently).

YuriyGavrilov commented 1 year ago

@jduo wow 🤩 thank you for such quick response. I will try to make tests also quickly but just get expired trial licenses. So maybe Monday or Tuesday will find a new tableau license and make tests.