简体   繁体   中英

Understanding Cause of NullPointerException in Java NIO Socket Channel

I've put together a simple echo type server app using java nio. While it is able to write the data, it always throws the following exception. Can anyone explain why this is happening? My code is below. Before the thread containing the run method is created I ensure the key.isAcceptable() is true.

Exception in thread "pool-1-thread-2" java.lang.NullPointerException

ExecutorService pool = Executors.newFixedPool(5);
...
try {
    pool.execute(                                           
        new Thread() {
            @Override public void run() {
                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                SocketChannel sc = null;
                try {
                    sc = ssc.accept();
                    String response = "Server thread (" + Thread.currentThread().getId() + ") Current time: " + new Date();
                    ByteBuffer bytes = encoder.encode(CharBuffer.wrap(response));
                    sc.write(bytes);
                } catch (java.io.IOException e) {
                    System.out.println("Exception: " + e.getMessage());                                                                              
                } finally {
                    try {
                        if (sc.isOpen()) sc.close(); // This is the line causing the exception to be thrown. If the check is changed to (sc != null) no exceptions are thrown.
                    } catch (java.io.IOException e) {
                        System.out.println("Exception: " + e.getMessage());
                    }
                }
            }
        }
    );
} catch (java.lang.Exception e) {
    System.out.println("Interrupted!");
}               

Exception in thread "pool-1-thread-2" 60java.lang.NullPointerException

  at EchoServer$1.run(EchoServer.java:61) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec 

utor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor .java:908) at java.lang.Thread.run(Thread.java:619)

我猜想ssc.accept返回的SocketChannel为null,这反过来意味着ServerSocketChannel处于非阻塞模式,并且没有挂起的连接。

The Javadoc for ServerSocketChannel says:

If this channel is in non-blocking mode then this method will immediately 
return null if there are no pending connections. Otherwise it will block 
indefinitely until a new connection is available or an I/O error occurs.

Are you sure ssc.accept() isn't returning null for just that reason?

As suggested by @IainM and @QuantumMechanic, you aren't checking 'sc' for null. If the NPE arises in sc.close(), 'sc' was null, I would say you got an NPE calling sc.write(), and another one in the finally{} block calling sc.close().

You also aren't checking the result of the write(), so you may be writing partial messages or indeed nothing at all. You also have a completely pointless test for sc.isOpen(). It is either null or open in this code, there is no other possibility.

And I don't know how you can call this thing an echo server when it doesn't read any input.

This is not the way to use NIO. The whole idea is that you don't need extra threads. There is something seriously wrong with your entire design.

You are also lying to yourself by printing "Interrupted!" on any exception, and concealing the actual exception by not printing its message or stack trace. This is not the way to use exceptions either.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM