Reputation: 397
Thanks in advance for your support.
I have used JSCH in my java application to call an exe file on remote server (Red Hat OS). I have noticed that my java application hangs for long time even thought the exe completes its job.
The exe file on remote server executes for more than 20 minutes as it needs to process huge text file.
In another case if I use a small input file and exe executes for a minute, the java application does not hung up.
Please advise why the application hungs up. Do i need to put some settings in the jsch code ?
Here is the code,
JSch jsch=null;
Session session=null;
java.util.Properties config=null;
ChannelSftp sftpChannel=null;
Channel channel=null;
InputStream in=null,error=null;
try
{
jsch=new JSch();
session=jsch.getSession(USERNAME, IP, PORT);
session.setPassword(PASSWORD);
logBasic("Node="+NODE_ID+", Host IP="+IP+", Port="+PORT+",Username="+USERNAME+", Dump Command="+MIG_TOOL_COMMAND+", Remote Path="+MIG_TOOL_PATH+"\n");
scriptOutput.append("Node="+NODE_ID+", Host IP="+IP+", Port="+PORT+",Username="+USERNAME+", Dump Command="+MIG_TOOL_COMMAND+", Remote Path="+MIG_TOOL_PATH+"\n");
FILE_NAME=KETTLE_HOME+"/"+LOGS_DIR+"/"+NODE_ID+"_master_slave_execution.log";
config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications",
"password");
session.setConfig(config);
session.setServerAliveInterval(60*60*60*1000);
session.connect();
channel=session.openChannel("exec");
//((ChannelExec)channel).setCommand(JAVA_COMMAND);
logBasic("Command = cd "+ MIG_TOOL_PATH+" && "+JAVA_COMMAND+" && "+MIG_TOOL_PATH+MIG_TOOL_COMMAND+" WORKING_MODE="+SLAVE_WORKING_MODE+" INPUT_FILE="+SDP_INPUT_FILENAME+".gz STAND_ALONE_FLAG="+STAND_ALONE_FLAG);
((ChannelExec)channel).setCommand("cd "+ MIG_TOOL_PATH+" && "+JAVA_COMMAND+" && "+MIG_TOOL_PATH+MIG_TOOL_COMMAND+" WORKING_MODE="+SLAVE_WORKING_MODE+" INPUT_FILE="+SDP_INPUT_FILENAME+".gz STAND_ALONE_FLAG="+STAND_ALONE_FLAG);
in=channel.getInputStream();
error=((ChannelExec)channel).getErrStream();
channel.connect();
scriptOutput.append("Error Ouput:\n");
byte[] tmp=new byte[1024];
boolean flag=true;
while(flag)
{
while(error.available()>0)
{
int i=error.read(tmp, 0, 1024);
if(i<0) break;
scriptOutput.append(new String(tmp, 0, i));
}
if(channel.isClosed()) flag=false;
try
{
Thread.sleep(threadSleepTime);
}
catch(Exception exception)
{
logError(exception.getMessage(), exception);
}
}
scriptOutput.append("Log Ouput:\n");
flag=true;
while(flag)
{
while(in.available()>0)
{
int i=in.read(tmp, 0, 1024);
if(i<0) break;
scriptOutput.append(new String(tmp, 0, i));
}
if(channel.isClosed()) flag=false;
try
{
Thread.sleep(threadSleepTime);
}
catch(Exception exception)
{
logError(exception.getMessage(), exception);
}
}
channel.disconnect();
channel=null;
session.disconnect();
Upvotes: 0
Views: 227
Reputation: 917
I tried what i said in comment and it works fine.
If your timeout is less than 100 seconds adjust setServerAliveInterval(100)
and if you need more than 9999 x 100s modify setServerAliveCountMax(9999)
If this does not works checked sshd_config
file on the server side to see if there is any settings that don't let you keep connection alive.
Java :
JSch jsch;
Session session;
Properties config;
Channel channel;
InputStream in, error;
long threadSleepTime = 100;
try {
jsch = new JSch();
session = jsch.getSession("timeoutuser", "timeoutHost", 22);
session.setPassword("pTimeout");
config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications", "password");
session.setConfig(config);
session.setServerAliveInterval(100);// Send null packet each 100s
session.setServerAliveCountMax(9999);// Send 9999 max null packet
session.connect(0);// No connection timeout
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand("./wait.sh");
in = channel.getInputStream();
error = ((ChannelExec) channel).getErrStream();
channel.connect();
byte[] tmp = new byte[1024];
boolean flag = true;
while (flag) {
while (error.available() > 0) {
int i = error.read(tmp, 0, 1024);
if (i < 0) {
break;
}
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
flag = false;
}
try {
Thread.sleep(threadSleepTime);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}
System.out.print("\nLog Ouput:\n");
flag = true;
while (flag) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
flag = false;
}
try {
Thread.sleep(threadSleepTime);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}
channel.disconnect();
session.disconnect();
} catch (JSchException | IOException ex) {
System.err.println(ex.getMessage());
}
Script wait.sh
#!/bin/bash
for i in {1..20}
do
sleep 2m
if [ $((RANDOM%5)) -gt 3 ]; then
echo "Error $i in process" 1>&2
fi
done
echo "Process done"
Output :
run:
Error 2 in process
Error 6 in process
Error 12 in process
Error 13 in process
Error 19 in process
Error 20 in process
Log Ouput:
Process done
BUILD SUCCESSFUL (total time: 40 minutes 0 seconds)
Upvotes: 2