Bug #97824 NullPointerException in NativeProtocol
Submitted: 28 Nov 2019 7:42 Modified: 31 Aug 22:29
Reporter: Roman Leventov Email Updates:
Status: No Feedback Impact on me:
Category:Connector / J Severity:S3 (Non-critical)
Version:8.0.18 OS:Mac OS X
Assigned to: CPU Architecture:Any

[28 Nov 2019 7:42] Roman Leventov
There may be a NullPointerException in NativeProtocol.java in line 661:

        } finally {
            if (timeoutMillis != 0) {
                try {
                    this.socketConnection.getMysqlSocket().setSoTimeout(oldTimeout); // <- this line
                } catch (IOException e) {
                    throw ExceptionFactory.createCommunicationsException(this.propertySet, this.serverSession, this.getPacketSentTimeHolder(),
                            this.getPacketReceivedTimeHolder(), e, getExceptionInterceptor());

this.socketConnection.getMysqlSocket() may return null.

How to repeat:
    private static Network network;
    private static MySQLContainer mysql;
    private static int mysqlPort;
    private static ToxiproxyContainer toxiproxy;
    private static ToxiproxyContainer.ContainerProxy proxy;
    private static String jdbcUrl;

    public static void setupContainers() {
        network = Network.newNetwork();
        mysql = (MySQLContainer) new MySQLContainer("mysql:5.7").withNetwork(network);
        mysqlPort = mysql.getMappedPort(MySQLContainer.MYSQL_PORT);
        toxiproxy = new ToxiproxyContainer().withNetwork(network);
        proxy = toxiproxy.getProxy(mysql, MySQLContainer.MYSQL_PORT);
        jdbcUrl = "jdbc:mysql://" + proxy.getContainerIpAddress() + ":" + proxy.getProxyPort() +
                "/" + mysql.getDatabaseName();

    public static void shutdownContainers() {
        //noinspection EmptyTryBlock: let try-with-resources do the work
        try (final Network ignore1 = network;
             final MySQLContainer ignore2 = mysql;
             final ToxiproxyContainer ignore3 = toxiproxy) {

    public void testHikariDbDisconnected() throws SQLException {
        HikariConfig config = new HikariConfig();
        try (HikariDataSource ds = new HikariDataSource(config)) {

            proxy.setConnectionCut(true); // Emulate db disconnection

            System.out.println(ds.getConnection().prepareCall("SELECT 1;").execute());
[31 Jul 22:29] Filipe Silva
Hi Roman,

Thank you for this bug report and your interest in Connector/J.

I'm sorry for the late reply, but can you provide a full stack trace with the exception, please?

[1 Sep 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[3 Sep 5:37] Marcle leo
Hi Filipe,
I had the same problem recently, and I have a reproducible test case here.

How to repeat:

import java.lang.reflect.Method;
import java.sql.*;

public class Demo {

    public static void main(String[] args) {
        Connection conn = null;
        Statement statement = null;
        try {
            // Set your connection parameters
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false" +
            // Set the breakpoint here or sleep the thread
            // Next, close the MySQL service and continue.
            Thread.sleep(30 * 1000);
            Method pingInternal = conn.getClass().getMethod("pingInternal", boolean.class, int.class);
            pingInternal.invoke(conn, true, 1000);
        } catch (Exception e) {
        } finally {
                if(statement!=null) statement.close();
            }catch(SQLException se2){
                if(conn!=null) conn.close();
            }catch(SQLException se){



My guess is that when the MySQL service was first shut down, the server-side TCP connection was in the FIN_WAIT_2/FIN_WAIT_2 state and could accept requests but not return data, so the following code is executing normally.
(The following code is taken from NativeProtocol#sendCommand.)

try {
	this.packetSequence = -1;
	send(queryPacket, queryPacket.getPosition());

} catch (CJException ex) {
	// don't wrap CJExceptions
	throw ex;
} catch (Exception ex) {
	throw ExceptionFactory.createCommunicationsException(this.propertySet, this.serverSession, this.getPacketSentTimeHolder(),
			this.getPacketReceivedTimeHolder(), ex, getExceptionInterceptor());

But this part of the code has an internal exception and sets the current this.socketConnection.getMysqlSocket() to null.
(The following code is taken from NativeProtocol#sendCommand.)

if (!skipCheck) {
	if ((COMMAND == NativeConstants.COM_STMT_EXECUTE) || (COMMAND == NativeConstants.COM_STMT_RESET)) {

	returnPacket = checkErrorMessage(command);

	if (this.queryInterceptors ! = null) {
		returnPacket = (NativePacketPayload) invokeQueryInterceptorsPost(queryPacket, returnPacket, false);
When executing to the finally statement block, when satisfying timeoutMillis ! = 0 condition, the following code throws the NPE.
(The following code is taken from NativeProtocol#sendCommand.)