Понимание причины исключения NullPointerException в сокете Java NIO - PullRequest
1 голос
/ 13 мая 2011

Я собрал простое серверное приложение типа эхо, используя java nio. Хотя он может записывать данные, он всегда выдает следующее исключение. Кто-нибудь может объяснить, почему это происходит? Мой код ниже. Перед созданием потока, содержащего метод run, я гарантирую, что key.isAcceptable() имеет значение true.

Исключение в теме "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!");
}               

Исключение в теме "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) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor .java: 908) at java.lang.Thread.run (Thread.java:619)

Ответы [ 3 ]

0 голосов
/ 13 мая 2011

Javadoc для ServerSocketChannel говорит:

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.

Вы уверены, что ssc.accept() не возвращает null только по этой причине?

0 голосов
/ 13 мая 2011

Как предлагают @IainM и @QuantumMechanic, вы не проверяете 'sc' на ноль.Если NPE возникает в sc.close (), 'sc' было нулевым, я бы сказал, что вы получили NPE, вызывающую sc.write (), и еще одну в блоке finally {}, вызывающем sc.close ().

Вы также не проверяете результат write (), поэтому вы можете писать частичные сообщения или вообще ничего.У вас также есть абсолютно бессмысленный тест для sc.isOpen ().В этом коде он либо нулевой, либо открытый, другой возможности нет.

И я не знаю, как можно назвать эту вещь эхо-сервером, когда он не читает никаких входных данных.

Это не способ использовать NIO.Вся идея в том, что вам не нужны дополнительные темы.Что-то серьезно не так с вашим дизайном.

Вы также лжете себе, печатая "Прервано!"на любое исключение и сокрытие фактического исключения, не печатая его сообщения или трассировки стека.Это также не способ использовать исключения.

0 голосов
/ 13 мая 2011

Я предполагаю, что SocketChannel, возвращаемый ssc.accept, имеет значение null, что, в свою очередь, означает, что ServerSocketChannel находится в неблокирующем режиме и нет ожидающего соединения.

...