Java ObjectInputStream readObject выбрасывает исключение NullPointerException - PullRequest
2 голосов
/ 19 сентября 2011

Я использую ObjectInputStream и ObjectOutputStream для моего клиента, чтобы общаться с сервером по TCP. Клиент не может получить ответ от сервера ... когда я перехожу в режиме отладки, ответ проходит нормально. Однако, если я запустлю программу без точки останова, она выдаст исключение NullPointerException.

Инициализация:

ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket socket = null;

socket = new Socket(server, port);
oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ois = new ObjectInputStream(socket.getInputStream());

Код, который ломается:

          try
            {
                oos.writeObject(request);   
                serverResponse = (Message) ois.readObject();
                output.append(serverResponse.data + "\n");
            } 
            catch(Exception ex) 
            {
                System.err.println("Error adding car to server: " + ex.getMessage());
                return;
            }

Приведенный выше код вызывает исключение NullPointerException. Если я использую точку останова и шаг за шагом, я получаю ответ сервера просто отлично. Я подтвердил, что в каждом случае сервер читает

Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАНИЕ STACK TRACE AT EX:

java.lang.NullPointerException
    at CarInventoryClient.actionPerformed(CarInventoryClient.java:251)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Ответы [ 4 ]

1 голос
/ 19 сентября 2011

Это было условие гонки.

ois = new ObjectInputStream (socket.getInputStream ());

В приведенной выше строке поток блокировался в конструкторе моего класса.Документация Java гласит, что она будет блокироваться до получения входных заголовков.Обработчик действия отправлял и получал пакет с сервера - это разбудило код конструктора и завершило инициализацию.

Когда был спящий поток или отладчик был присоединен, код конструктора завершился бы до того, какданные были получены.Однако в режиме реального времени readObject вызывался до завершения разблокированной инициализации.Вот почему ois считался нулевым.

1 голос
/ 19 сентября 2011

Я думаю, что вывод этой строки, вероятно, сбивает вас с толку:

System.err.println("Error adding car to server: " + ex.getMessage());

Исключению не требуется сообщение, поэтому выводится следующее:

Это совершенно нормально (и немного неудобно):
Error adding car to server: null

Путем печати только сообщения об исключении, которое вы пропускаете при регистрации важной информации, такой как тип исключения, а также трассировка стека исключений. Вам лучше позвонить ex.printStackTrace(). Который печатает класс исключения, сообщение и трассировку стека исключения.

1 голос
/ 19 сентября 2011

(уточнение комментария выше по дидактическим причинам. ОП подтвердил.)

Если вы получаете трассировку стека, которая начинается с данной строки, это означает, что выброс произошел на этой самой строке, а не в методе, вызванном из этой строки . Итак, глядя на обсуждаемую строку:

> java.lang.NullPointerException
>     at CarInventoryClient.actionPerformed(CarInventoryClient.java:251)

serverResponse = (Message) ois.readObject();

Единственный способ этой самой линии может бросить NPE, это если ois равен нулю.

1 голос
/ 19 сентября 2011

Я предлагаю вам очистить выходной поток перед тем, как пытаться прочитать входной поток.

Переменная ex не должна быть null.Можете ли вы дать нам точную строку, на которой происходит исключение.

Вы должны напечатать сообщение целиком.Я подозреваю, что не печатание типа и строки, исключение происходит, не помогает.Если у вас есть исключение без сообщения, getMessage () вернет null

try

 ex.printStackTrace();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...