Java ObjectInputStream readObject抛出NullPointerException

时间:2011-09-18 20:02:59

标签: java tcp

我正在使用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。如果我使用断点并单步执行,我会得到服务器响应就好了。我已经确认在每个实例中服务器都在读

非常感谢任何帮助!

在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 个答案:

答案 0 :(得分:1)

我建议您在尝试读取输入流之前刷新输出流。

变量ex不应该是null。你能告诉我们发生异常的确切行吗。

您应该打印整条消息。我怀疑不打印类型和行正在发生的异常没有帮助。如果您有没有消息的异常,则getMessage()将返回null

 ex.printStackTrace();

答案 1 :(得分:1)

我认为这一行的输出可能让你感到困惑:

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

异常不需要消息,因此打印出来是完全正常的(也有点不方便):

Error adding car to server: null

通过仅打印异常消息,您在记录关键信息(例如异常类型以及异常堆栈跟踪)时遗漏了这些消息。你最好打电话给ex.printStackTrace()。其中打印异常类,消息和异常的堆栈跟踪。

答案 2 :(得分:1)

(由于教学原因,上述评论的详细说明.OP已确认。)

如果你得到一个带有给定行的开始的堆栈跟踪,则意味着该行发生了 - 而不是从该行调用的方法。所以看看有问题的一行:

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

serverResponse = (Message) ois.readObject();

非常行可以抛出NPE的唯一方法是ois为空。

答案 3 :(得分:1)

这是竞争条件。

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

以上行导致线程在我的类的构造函数中阻塞。 Java的文档声明它将阻塞,直到收到输入标头。操作处理程序正在发送然后从服务器接收数据包 - 这会唤醒构造函数代码并完成初始化。

当线程休眠或连接了调试器时,构造函数代码将在收到数据之前完成。但是,在实时执行中,在未阻塞的初始化完成之前调用了readObject。这就是ois被视为无效的原因。