I have the following code:
JSch jsch = new JSch();
jsch.setKnownHosts(dotSshDir + "/known_hosts");
jsch.addIdentity(dotSshDir + "/id_rsa");
Session session = jsch.getSession(userName, hostname, 22);
session.connect();
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.setInputStream(null);
channel.setErrStream(System.err);
Reader reader = new InputStreamReader(channel.getInputStream());
char[] buf = new char[1024];
int numRead;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
result.append(readData);
buf = new char[1024];
}
It's hanging trying to read from the reader. How do I fix this? How do I go about hunting down what's happening?
The accepted answer by @NoelYap is wrong.
One has to read the output continuously, while waiting for the command to finish. Otherwise, if the command produces enough output to fill in an output buffer, the command will hang, waiting for the buffer to be consumed, what never happens. So you get a deadlock.
The following example reads both stdout and stderr continuously, while monitoring a command status. It is based on the official JSch
exec.java
example (just adds a reading of stderr).If you add
while (!channel.isClosed()) {}
after thechannel.connect();
, you will see that with a sufficiently largei
in the shellfor
loop (10000 is enough with in my environment), the loop never finishes.