Details
Description
When using the TelnetClient class, a NullPointerException may occur when calling the disconnect method twice, in the _closeOutputStream method called under the hood, if the Telnet connection is lost (for instance, server is hardly shut down).
1. The first call to disconnect resets completely the TelnetClient instance.
2. The second call to disconnect leads to the NPE exception, because the _output_ property is null, in the _closeOutputStream method.
NOTE: the NPE does not occur with JDK 8, because, the first call to disconnect throws an I/O exception (socket is closed), leaving the TelnetClient instance with a non-null _output_ property. Then a second call to disconnect does not throw a NPE. It seems the JDK 8 behaves differently when a client socket loses a connection. So there is also a bug with JDK 8, as disconnection shall close quietly resources without an I/O exception, and without leaving non-null resources, and then disconnect the client socket. The SocketClient.disconnect is a good implementation to start with.
The problem is that the TelnetOutputStream class closes the Socket output stream under the hood, but doesn't check if it is null and doesn't reset it to null once done. The implementation of the TelnetOutputStream is quite strange, as there is a cycling dependency between this class and the TelnetClient class. The TelnetClient class shall handle itself the close of its internal resources, and disconnect the client socket. But this responsibility is delegates to the TelnetOutputStream.
Here's the stack trace of the NPE exception:
java.lang.NullPointerException
at org.apache.commons.net.telnet.TelnetClient._closeOutputStream(TelnetClient.java:83)
at org.apache.commons.net.telnet.TelnetOutputStream.close(TelnetOutputStream.java:163)
at org.apache.commons.net.telnet.TelnetClient.disconnect(TelnetClient.java:124)
A way to workaround this bug, is to always check if the TelnetClient instance is connected, before calling the disconnect method.