Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
2.7.5
-
None
-
Java 11 / Linux / JavaMelody (but should not be related)
Description
When cancelling an other query from an other thread, you might get an NPE in rare cases:
java.lang.NullPointerException
|
at org.mariadb.jdbc.MariaDbStatement.skipMoreResults(MariaDbStatement.java:1187)
|
at org.mariadb.jdbc.MariaDbStatement.cancel(MariaDbStatement.java:981)
|
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
|
at net.bull.javamelody.JdbcWrapper$StatementInvocationHandler.invoke(JdbcWrapper.java:163)
|
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:306)
|
at com.sun.proxy.$Proxy345.cancel(Unknown Source)
|
at io.ebean.util.JdbcClose.cancel(JdbcClose.java:76)
|
As you see, 'protocol' is null in https://github.com/mariadb-corporation/mariadb-connector-j/blob/2.7.5/src/main/java/org/mariadb/jdbc/MariaDbStatement.java#L1187
I investigate a bit and have the following explanation for the bug:
Thread #1 starts a query
Thread #2 tries to cancel the query.
It invokes L980 protocol.cancelCurrentQuery() successfully
Thread #1 now closes the query and sets protocol = null
When Thread #2 tries to execute L981, which calls L1187 protocol.skip() - you get an NPE.
There is no kind of locking the access of protocol and this can be modified in a concurrent thread.
Unfortunately, I cannot provide a test. The bug is very hard to reproduce and happens only in production...
Side note: I think the bug may not happen with 3.x, because the code is totally different (but we did not update to 3.x, yet)
Thanks for detailed explaination.
This will be corrected in next version.