Java ObjectInputStream readObject 抛出 NullPointerException

发布于 2024-12-05 03:24:38 字数 3430 浏览 1 评论 0原文

我正在使用 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)

I am using an ObjectInputStream and ObjectOutputStream for my client to talk to a server over TCP. The client is not able to receive a response back from the server... when I step through in debug mode the response goes through fine. However, if I run the program without a break point it will throw a NullPointerException exception.

Initialization:

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());

Code that breaks:

          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;
            }

The code above is throwing the NullPointerException. If I use a break point and step through, I get a server response just fine. I have confirmed that in every instance the server is reading the

Any help would be greatly appreciated!

EDIT 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

幻想少年梦 2024-12-12 03:24:38

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

变量 ex 不应为 null。您能否告诉我们发生异常的确切行数?

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

尝试

 ex.printStackTrace();

I suggest you flush the output stream before attempting to read the input stream.

The variable ex shouldn't be null. Can you give us the exact line the exception occurs on.

You should print the whole message. I suspect not printing the type and line the exception is occurring is not helping. If you have an exception with no message getMessage() will return null

try

 ex.printStackTrace();
往事随风而去 2024-12-12 03:24:38

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

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

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

Error adding car to server: null

通过仅打印异常消息,您将错过记录关键信息例如异常类型以及异常堆栈跟踪。您最好调用 ex.printStackTrace()。它打印异常类、消息和异常的堆栈跟踪。

I think the output of this line is probably confusing you:

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

An exception does not require a message so it is perfectly normal (as well as a bit inconvenient) that this prints:

Error adding car to server: null

By only printing the exception message you are missing out on logging crucial information such as the exception type as well as the exceptions stack trace. You are better off calling ex.printStackTrace(). Which prints the exception class, message and the stack trace of the exception.

尽揽少女心 2024-12-12 03:24:38

(出于说教原因,对上面的注释进行了详细说明。OP 已确认。)

如果您得到以给定行开始的堆栈跟踪,则意味着抛出发生在该行上 -不在从该行调用的方法内。因此,看看有问题的行:

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

serverResponse = (Message) ois.readObject();

这一行可能抛出 NPE 的唯一方法是 ois 为 null。

(An elaboration of a comment above, for didactic reasons. OP has confirmed.)

If you get a stack trace that begins with a given line, it means the throw happened on that very line - not within a method called from that line. So looking at the line in question:

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

serverResponse = (Message) ois.readObject();

The only way this very line could throw an NPE is if ois is null.

秋日私语 2024-12-12 03:24:38

这是一个竞争条件。

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

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

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

This was a race condition.

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

The above line was causing the thread to block in my class's constructor. Java's documentation states that it will block until input headers are received. The action handler was sending then receiving a packet from the server - this woke the constructor code back up and finished the initialization.

When there was a thread sleep, or the debugger was attached, the constructor code would complete before the data was received. However, in real time execution, readObject was being called before the unblocked initialization could finish. This is why ois was being seen as null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文