There is a large race condition in J2SSH; in the ChannelInputStream class to be precise. When the channel is closed before all data is read from the ChannelInputStream, it will report that it is EOF, even if there is still incoming data in the message store!

This causes the output of commands to be lost either completely or partially on a random basis.

The cause is this while loop on line 267 of ChannelnputStream (the same bug is repeated a few lines further on for stdout):

while ((msg == null) && !isClosed()) {
    // … read msg …

isClosed() returns true if the underlying message store is closed, regardless of whether there are still message waiting in the message store. Since the channel is closed automatically when the command is finished, and the channel closes the message stores when it is closed, this while loop will always be skipped after the command has finished and if any of the command's output is still buffered in the message store it will be lost.

One possible short term solution is to simply remove the !isClosed() from the conditions of the two while loops. This will allow the getMessage() method of the message store to throw a MessageStoreEOFException when the message store is closed and there are no more messages buffered.

Really all this code should be refactored though. Relying on exceptions for flow control is very ugly.