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

java.lang.NullPointerException: Attempt to invoke virtual method 'void java.net.Socket.close()' on a null object reference #957

Open
wengbiancheng opened this issue Dec 9, 2019 · 7 comments

Comments

@wengbiancheng
Copy link

Describe the bug
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.net.Socket.close()' on a null object reference
I have encountered this error many times, but I cannot reproduce it because I found that the error seems to be caused by multi-threaded concurrency.
I found that socket.close () appears in two different threads.
One is the reconnect() and it will call the reset():

private void reset() {

	Thread current = Thread.currentThread();
	if (current == writeThread || current == connectReadThread) {
		throw new IllegalStateException("You cannot initialize a reconnect out of the websocket thread. Use reconnect in another thread to insure a successful cleanup.");
	}
	try {
		closeBlocking();
		if( writeThread != null ) {
			this.writeThread.interrupt();
			this.writeThread = null;
		}
		if( connectReadThread != null ) {
			this.connectReadThread.interrupt();
			this.connectReadThread = null;
		}
		this.draft.reset();
		if( this.socket != null ) {
			this.socket.close();
			this.socket = null;
		}
	} catch ( Exception e ) {
		onError( e );
		engine.closeConnection( CloseFrame.ABNORMAL_CLOSE, e.getMessage() );
		return;
	}
	connectLatch = new CountDownLatch( 1 );
	closeLatch = new CountDownLatch( 1 );
	this.engine = new WebSocketImpl( this, this.draft );
}

One is in the WebsocketWriteThread:

private class WebsocketWriteThread implements Runnable {


	@Override
	public void run() {
		Thread.currentThread().setName( "WebSocketWriteThread-" + Thread.currentThread().getId() );
		try {
			runWriteData();
		} catch ( IOException e ) {
			handleIOException( e );
		} finally {
			closeSocket();
			writeThread = null;
		}
	}

	/**
	 * Closing the socket
	 */
	private void closeSocket() {
		try {
			if( socket != null ) {
				socket.close();
			}
		} catch ( IOException ex ) {
			onWebsocketError( webSocketClient, ex );
		}
	}
}

Obviously the reconnect thread and the write thread are not the same thread.This reminds me of a piece of code I saw elsewhere.

public class GcsTest {

private static String mStr = null;

private static void printStrLength() {
    if (null != mStr) {
        int len = mStr.length();
        System.out.println("length = " + len);
    }
}

public static void main(String[] args) {
    GThreadA threadA = new GThreadA();
    GThreadB threadB = new GThreadB();
    threadA.start();
    threadB.start();
}

static class GThreadA extends Thread {
    @Override
    public void run() {
        while (true) {
            if (null == mStr) {
                mStr = "Gcs";
            } else {
                mStr = null;
            }
        }
    }
}

static class GThreadB extends Thread {
    @Override
    public void run() {
        while (true) {
            printStrLength();
        }
    }
}}

It will have a null pointer error.It may take some time to run before the error occurs.After threadB just judged if (null! = mStr), it switched to threadA. At this time, threadA also judged that mStr was not null, so it set mStr to null, and then switched to threadB. When threadB gets the length A null pointer exception occurred.

So when reconnect () happens, is it possible that there are some conditions that triggered closeSocket in writeThread.And when reconnectThread sets the socket to null, just writeThread switches to socket.close().So it happened a null pointer exception and WebsocketWriteThread does not catch null pointer exception,it only catches IOException,so the entire application crashed.

Environment(please complete the following information):

  • Version used:1.4.0
  • Java version:1.8.0_131
  • Operating System and version: Android 9
@StellaSong12
Copy link

same situation, there may should be thread locked
if( socket != null ) {
socket.close();
}

@pawankgupta-se
Copy link

pawankgupta-se commented May 11, 2020

Hi @marci4
I am also facing this issue, while client wants to disconnects sever getting this java.lang.NullPointerException. Find the below log. Let me know if you need more information

2020-05-11 20:45:56.998 18418-18701/com.example.websocket.receiver E/org.java_websocket.server.WebSocketServer: [WebSocketSelector-120593] WebSocketServer::handleFatal Shutdown due to fatal errorjava.lang.NullPointerException: ssl == null
        at com.android.org.conscrypt.NativeCrypto.SSL_set_timeout(Native Method)
        at com.android.org.conscrypt.SslWrapper.setTimeout(SslWrapper.java:101)
        at com.android.org.conscrypt.ActiveSession.invalidate(ActiveSession.java:147)
        at com.android.org.conscrypt.DelegatingExtendedSSLSession.invalidate(DelegatingExtendedSSLSession.java:120)
        at org.java_websocket.SSLSocketChannel2.close(SSLSocketChannel2.java:354)
        at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:511)
        at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:545)
        at org.java_websocket.server.WebSocketServer.handleIOException(WebSocketServer.java:608)
        at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:361)
        at java.lang.Thread.run(Thread.java:764)
2020-05-11 20:45:56.999 18418-18701/com.example.websocket.receiver W/System.err: java.lang.NullPointerException: ssl == null
2020-05-11 20:45:57.000 18418-18701/com.example.websocket.receiver W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_set_timeout(Native Method)
2020-05-11 20:45:57.000 18418-18701/com.example.websocket.receiver W/System.err:     at com.android.org.conscrypt.SslWrapper.setTimeout(SslWrapper.java:101)
2020-05-11 20:45:57.000 18418-18701/com.example.websocket.receiver W/System.err:     at com.android.org.conscrypt.ActiveSession.invalidate(ActiveSession.java:147)
2020-05-11 20:45:57.001 18418-18701/com.example.websocket.receiver W/System.err:     at com.android.org.conscrypt.DelegatingExtendedSSLSession.invalidate(DelegatingExtendedSSLSession.java:120)
2020-05-11 20:45:57.001 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.SSLSocketChannel2.close(SSLSocketChannel2.java:354)
2020-05-11 20:45:57.001 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:511)
2020-05-11 20:45:57.002 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:545)
2020-05-11 20:45:57.002 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.handleIOException(WebSocketServer.java:608)
2020-05-11 20:45:57.002 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:361)
2020-05-11 20:45:57.003 18418-18701/com.example.websocket.receiver W/System.err:     at java.lang.Thread.run(Thread.java:764)
2020-05-11 20:45:57.004 18418-18701/com.example.websocket.receiver E/WebSocketReceiver: <1d711>  ssl == null
2020-05-11 20:45:57.014 18418-18701/com.example.websocket.receiver E/org.java_websocket.server.WebSocketServer: [WebSocketSelector-120593] WebSocketServer::handleFatal Interrupt during stopjava.lang.NullPointerException: ssl == null
        at com.android.org.conscrypt.NativeCrypto.SSL_set_timeout(Native Method)
        at com.android.org.conscrypt.SslWrapper.setTimeout(SslWrapper.java:101)
        at com.android.org.conscrypt.ActiveSession.invalidate(ActiveSession.java:147)
        at com.android.org.conscrypt.DelegatingExtendedSSLSession.invalidate(DelegatingExtendedSSLSession.java:120)
        at org.java_websocket.SSLSocketChannel2.close(SSLSocketChannel2.java:354)
        at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:511)
        at org.java_websocket.WebSocketImpl.closeConnection(WebSocketImpl.java:545)
        at org.java_websocket.server.WebSocketServer.handleIOException(WebSocketServer.java:608)
        at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:361)
        at java.lang.Thread.run(Thread.java:764)
2020-05-11 20:45:57.014 18418-18701/com.example.websocket.receiver W/System.err: java.lang.InterruptedException
2020-05-11 20:45:57.014 18418-18701/com.example.websocket.receiver W/System.err:     at java.lang.Object.wait(Native Method)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at java.lang.Object.wait(Object.java:422)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at java.lang.Thread.join(Thread.java:1262)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.stop(WebSocketServer.java:265)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.stop(WebSocketServer.java:270)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.handleFatal(WebSocketServer.java:635)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:371)
2020-05-11 20:45:57.015 18418-18701/com.example.websocket.receiver W/System.err:     at java.lang.Thread.run(Thread.java:764)
2020-05-11 20:45:57.016 18418-18701/com.example.websocket.receiver E/WebSocketReceiver: <1d711>  null
2020-05-11 20:45:57.017 18418-18701/com.example.websocket.receiver V/org.java_websocket.AbstractWebSocket: [WebSocketSelector-120593] AbstractWebSocket::stopConnectionLostTimer Connection lost timer stopped
a

@marci4
Copy link
Collaborator

marci4 commented May 11, 2020

@pawankgupta-se looks like this issue is caused by the OS?

@pawankgupta-se
Copy link

pawankgupta-se commented May 11, 2020

@marci4 Not sure, but something related to Thread. But I have very simple code as of now. Not introducing any other thread from my side. And this issue is consistent.

@marci4
Copy link
Collaborator

marci4 commented May 11, 2020

@pawankgupta-se there are a few other issues which you can find with a quick google e.g. square/okhttp#4260

@runfengai
Copy link

runfengai commented May 31, 2020

I hava the same problem. There are two solutions for me.

  1. use UncaughtExceptionHandler to catch the exception.
  2. Customize a class similar to WebSocketClient,and rewrite two methods: reset() & closeSocket() in WebsocketWriteThread

`

    //in custom WebSocketClient
    private final Object obj = new Object();
    private void reset() {
        //...
        synchronized (obj) {
            if (this.socket != null) {
                this.socket.close();
                this.socket = null;
            }
        }
        //...
    }

`

`

    //in WebsocketWriteThread,we rewrite
    private void closeSocket() {
        try {
            synchronized (obj) {
                if (socket != null) {
                    socket.close();
                }
            }
        } catch (IOException ex) {
            onWebsocketError(webSocketClient, ex);
        }
    }

`

@hhyq520
Copy link

hhyq520 commented Dec 28, 2020

This problem has broken down a lot,I hope the author can solve this problem in the next version。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants