我正在使用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)
答案 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被视为无效的原因。