Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception thrown while establishing a new JDBC connection after Thread.stop #1461

Closed
MohamedKamarudeen opened this issue Jul 5, 2023 · 4 comments
Assignees
Labels
invalid status-triage_done Initial triage done, will be further handled by the driver team

Comments

@MohamedKamarudeen
Copy link

MohamedKamarudeen commented Jul 5, 2023

Scenario:

Establish a new Snowflake JDBC connection
Execute any query by using the PreparedStatement
Do a Thread.stop() call to the query execution thread while query execution is in progress
After Thread.stop() has successfully completed, try establishing a new JDBC connection, below exception is thrown
Exception Message:
Message: Invalid state: Connection pool shut down. A potential cause is closing of a connection when a query is still running..

Exception Stack Trace:

Caused by: java.lang.IllegalStateException: Connection pool shut down
	at net.snowflake.client.jdbc.internal.apache.http.util.Asserts.check(Asserts.java:34) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:269) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:176) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.internal.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.RestRequest.execute(RestRequest.java:220) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.RestRequest.execute(RestRequest.java:67) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.HttpUtil.executeRequestInternal(HttpUtil.java:751) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.HttpUtil.executeRequest(HttpUtil.java:684) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.HttpUtil.executeGeneralRequest(HttpUtil.java:601) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.SessionUtil.newSession(SessionUtil.java:612) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.SessionUtil.openSession(SessionUtil.java:292) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.core.SFSession.open(SFSession.java:481) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initialize(DefaultSFConnectionHandler.java:112) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initializeConnection(DefaultSFConnectionHandler.java:85) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.SnowflakeConnectionV1.initConnectionWithImpl(SnowflakeConnectionV1.java:116) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:96) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:187) ~[snowflake-jdbc-3.13.33.jar:3.13.33]
	at java.sql.DriverManager.getConnection(DriverManager.java:664) ~[?:1.8.0_301]
	at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[?:1.8.0_301]

Not able to establish a new connection once this exception has occurred.

Possible cause :
Internally a field isShutDown is maintained by net.snowflake.client.jdbc.internal.apache.http.impl.conn.PoolingHttpClientConnectionManager which might be set to true when Thread.stop() is called. On subsequent calls as this flag is set to true new connection seems to be rejected by the above exception, as net.snowflake.client.jdbc.internal.apache.http.impl.conn.PoolingHttpClientConnectionManager is maintained as SingletonObject (static).

Able to establish a new JDBC connection after this Java application is killed and restarted. Is there any other way to establish a new connection without kill and restart?

@sfc-gh-wfateem
Copy link
Collaborator

@MohamedKamarudeen like I mentioned in your other issue, you don't want to call Thread.stop().
You mentioned that you tried using Thread.interrupt() but you had the following observation:

Noticed that the Thread.interrupt() call takes more than a minute when executing the query. Is there any way to reduce the long interrupt time?

First off, did you avoid the problem that you originally reported in this issue by doing so?

Do you have sample code of what it is exactly you're doing in the different threads involved and when you invoke the Thread.interrupt() method?

@MohamedKamarudeen
Copy link
Author

@sfc-gh-wfateem - Please find the attached program below to test the interruption that was not honored.

import java.sql.*;

class SnowflakeJDBCExample implements Runnable {
    static String SNOWFLAKE_URL = "jdbc:snowflake:*******";
    static String USERNAME = "*******";
    static String PASS = "*******";
    @Override
    public void run() {
        try {
            Connection connection = DriverManager.getConnection(SNOWFLAKE_URL, USERNAME, PASS);
            System.out.println("Connection Established");

            ResultSet resultSet;
            while(true) {
                resultSet = connection.getMetaData().getTables(null, "%", "%", new String[]{"TABLE", "VIEW", "ALIAS", "SYNONYM"});
                System.out.println("Meta fetch completed");
            }
        } catch (Exception e) {
            System.out.println("Exception occurred while performing IO operations: "+ e);

            StackTraceElement[] stackTrace = e.getStackTrace();

            System.out.println("---------------------------------");
            if (stackTrace != null) {
                for (StackTraceElement element : stackTrace) {
                    System.out.println(element.toString());
                }
            }
            System.out.println("---------------------------------");
        } finally {
            System.out.println("Executing finally block");
            Test.snowflakeJDBCExample = null;
        }
    }
}


public class Test {

    static volatile SnowflakeJDBCExample snowflakeJDBCExample = new SnowflakeJDBCExample();
    public static void main(String[] args) throws SQLException, InterruptedException {
        try {

            Thread snowflakeThread = new Thread(snowflakeJDBCExample);

            snowflakeThread.start();
            System.out.println("Calling snowflakeThread.isInterrupted() before make interrupt call: "+snowflakeThread.isInterrupted());

            Thread.sleep(10000);

            System.out.println("Calling snowflakeThread.isInterrupted() before make interrupt call: "+snowflakeThread.isInterrupted());

            snowflakeThread.interrupt();

            System.out.println("Calling snowflakeThread.isAlive() after made interrupt call "+snowflakeThread.isAlive());
            System.out.println("Calling snowflakeThread.isInterrupted() after made interrupt call"+snowflakeThread.isInterrupted());

            while(true) {
                Thread.sleep(1000);

                if(snowflakeJDBCExample==null)
                    break;
            }
            
        } catch (Error | Exception e) {
            System.out.println("Exception occurred in main thread: "+e);
        }

        //Try to establish a new connection
        Connection connection = DriverManager.getConnection(SnowflakeJDBCExample.SNOWFLAKE_URL, SnowflakeJDBCExample.USERNAME, SnowflakeJDBCExample.PASS);
    }
}

@sfc-gh-igarish
Copy link
Collaborator

@sfc-gh-wfateem any update? is it reproducible?

@sfc-gh-dszmolka sfc-gh-dszmolka added the status-triage_done Initial triage done, will be further handled by the driver team label Apr 26, 2024
@sfc-gh-wfateem
Copy link
Collaborator

Closing this because as I highlighted a while back, you shouldn't be calling Thread.stop().
I'll look into the Thread.interrupt() call in the other issue #1482

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid status-triage_done Initial triage done, will be further handled by the driver team
Projects
None yet
Development

No branches or pull requests

4 participants