Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#10 jre 1.5 and silktest printing to stdout issue

open
nobody
None
5
2006-07-31
2006-07-31
No

I think that this is a more difficult issue for
someone external to debug or recreate than it would be
me just due to the fact of one of the software
components involved(Silktest). But here goes. I was
using JSch 0.1.28 to create an SSHExec command line
util for our testing group to have functionality
similar to rexec. It is very similar to the Exec.java
example included in the JSch distribution, with the
exception that I removed the dialogs that come up and
I have the setTrust set to true, so that it
automatically accepts connections without asking about
the host. And everything gets passed in on the
command line: host username password command and a
timeout value.

Here is the code for the simple util. I use the Ant
SSHUserInfo for my UserInfo implementation.

-------------------------------------
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

import
org.apache.tools.ant.taskdefs.optional.ssh.SSHUserInfo;

import java.io.InputStream;

import java.lang.RuntimeException;

import java.nio.charset.Charset;

public class SSHExec {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
if (args.length < 5) {
throw new RuntimeException(
"usage: SSHExec.jar <host> <username>
<password> <command> <timeout(secs)>");
}

String host = args[0];
String username = args[1];
String password = args[2];
String cmd = args[3];
Double timeout = new Double(args[4]);
boolean trust = true;

/* if(args.length==6) {

if(args[5].equalsIgnoreCase("-trust")) {
trust = true;
}
}*/
try {

JSch jsch = new JSch();
Session session =
jsch.getSession(username, host, 22);
session.setTimeout(timeout.intValue() *
1000);

UserInfo ui = new SSHUserInfo(password,
trust);
session.setUserInfo(ui);
session.connect();

Channel channel =
session.openChannel("exec");
((ChannelExec) channel).setCommand(cmd);
//channel.setXForwarding(true);
//channel.setInputStream(System.in);
channel.setInputStream(null);
channel.setOutputStream(System.out);
((ChannelExec)
channel).setErrStream(System.err);

InputStream in = channel.getInputStream();
channel.connect();

byte[] tmp = new byte[1024];
String output = new String();

while (true) {
if (session.isConnected() == false) {
throw new
RuntimeException("Connection Timed Out");
}

while (in.available() > 0) {

int i = in.read(tmp, 0, 1024);

if (i < 0) {
break;
}

output = output + new String(tmp,
0, i);

// System.out.print(new
String(tmp, 0, i));
}

if (channel.isClosed()) {
//
System.out.println("exit-status:
"+channel.getExitStatus());
break;
}

try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}

/*if(channel.getExitStatus()!=0) {
throw new Exception("Error:
SSHExec command did not return 0 to the operating
system.");
}*/
channel.disconnect();
session.disconnect();
System.out.print(output.replaceAll("\n",
"\r\n"));
} catch (Exception e) {

System.err.println(e.getLocalizedMessage());
System.exit(-1);
}
}
}
-------------------------------------

The problem that I am encountering is the test group
here uses Silktest and a combination of either jre
1.4.2/1.5 or the jdk of the same versions. I had this
code running fine with java 1.4.2, but one of the
execution team was using the jre 1.5, and it appeared
to break my code here. The main thing is that no data
would get returned back, from the run of this util. I
can using jre 1.5 run this from the command line and
it returns the output on the command line as expected.
Just in when silktest runs this same command that I
tried on the command line it loses the output. So I
was thinking that it had something to do with some
interaction between Silktest and Java JRE 1.5, but I
also found out that if I comment out the line:

((ChannelExec)
channel).setErrStream(System.err);

That I get output returned from the command executed
in silktest. Of course it still works on the command
line as well, the only thing that I lose is the
ability to get back the stderr output from the
remotely executed command back to my code.

I step through debugging my code in eclipse and have
the following Expressions defined so that every step
in my code would print something on stderr and stdout.

System.out.println("Test.out")
System.err.println("Test.err")

If I set the errstream then when I get to the line

channel.connect();

I lose the Test.err lines that get printed out. Even
after I close out the channel, the stderr is lost.
Just curious as I remember seeing something a while
back about the stderr not getting closed properly. I
figured I would start a thread about this with the
information I had to start with and then would
continue to look at the issue on my own as well to get
some better information. I don't think that this fact
of me losing the stderr has anything to do with my not
getting info returned back when I run the SSHExec util
via silktest.

Discussion