I'm writing Java GUI program for static route management using SSH. My code is as follows:
import com.jcraft.jsch.*;
import java.io.*;
public class Konsep {
String status;
static String username;
static String hostname;
String inputcommand;
String output;
static Session session;
JSch jsch = new JSch();
public String status(String stringstatus) {
stringstatus = status;
return stringstatus;
}
public String InputCommand(String inputcommandstatus) {
inputcommandstatus = inputcommand;
return inputcommandstatus;
}
public void connect(String usernamelokal, String hostnamelokal,
String password, int port) {
// JSch jsch=new JSch();
try {
Session sessionlokal = jsch.getSession(usernamelokal,
hostnamelokal, port);
sessionlokal.setPassword(password);
UserInfo ui = new UserInfoku.Infoku();
sessionlokal.setUserInfo(ui);
sessionlokal.setTimeout(0);
sessionlokal.connect();
status = "tersambung \n";
username = usernamelokal;
hostname = hostnamelokal;
session = sessionlokal;
System.out.println(username + " " + hostname);
} catch (Exception e) {
System.out.println(e);
status = "Exception = \n " + e + "\n";
}
}
public void disconnect() {
// JSch jsch=new JSch();
try {
Session sessionlokal = jsch.getSession(username, hostname);
// System.out.println(username +" "+ hostname);
sessionlokal.disconnect();
status = "wes pedhoott \n";
} catch (Exception e) {
System.out.println(e);
status = "Exception = \n " + e + "\n";
}
}
public void addRoute() {
// JSch jsch=new JSch();
System.out.println(username + " " + hostname);
try {
Session sessionlokal = session; // =jsch.getSession(username, hostname);
Channel channel = sessionlokal.openChannel("exec");
((ChannelExec) channel).setCommand(inputcommand);
channel.setInputStream(null);
channel.connect();
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
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()) {
System.out.println("exit-status: "
+ channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
} catch (Exception e) {
System.out.println(e);
}
}
}
The problem is when I call the connect method and then calling the addroute, the program returns
root 192.168.50.2
root 192.168.50.2
com.jcraft.jsch.JSchException: session is down
I've been trying to get session status with either
Session sessionlokal=session; //returns com.jcraft.jsch.JSchException: ChannelExec
or
Session sessionlokal=jsch.getSession(username, hostname); //returns session is down
I've also tried to use keepalive, but its not working either.
My intention is to create a session to host (log in), while leaving the session up, execute a command or commands and maybe executing other commands later, and then closing the session when its not needed (log out). I've been searching on this forum and I found this question but the code is create a method to define a command to execute first, and then creating the session, call the command's method and close the session.
Any ideas about how to do as I mentioned above ?
A Session represents a connection to a SSH server. One session can contain multiple Channel s of various types, created with openChannel(java. lang. String) . A session is opened with connect() and closed with disconnect() .
JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs.
No, it's not risky to give JSch your private key. In order to make asymmetric cryptography work, you have to use a private key. In this case, JSch is doing the job for you, but it won't send it to anyone, it's just using it to decrypt data you receive, and encrypt data you send.
After trying Session.sendKeepAliveMsg()
without success, I came to the following solution which seems to be rather stable:
private Session getSession() throws Exception {
try {
if (!session.isConnected()) {
logger.info("Session successfully tested, use it again.");
session.connect();
}
} catch (Throwable t) {
logger.info("Session terminated. Create a new one.");
session = jsch.getSession(user, host, port);
session.setConfig(config);
session.connect();
}
return session;
}
Update: Some days later it failed.
I tried to test it by killing the open session on the server. All prior versions I tested this way showed the exact same behavior, regardless whether the problem popped up after waiting some days or killing the server process, so I thought this test - and its outcome for the above solution - to be meaningful. Unfortunately, it isn't.
I'm going to try some other ways to fix it and keep you up to date.
Update 2: Final solution, guaranteed inelegant and working:
private Session getSession() throws Exception {
try {
ChannelExec testChannel = (ChannelExec) session.openChannel("exec");
testChannel.setCommand("true");
testChannel.connect();
if(logger.isDebugEnabled()) {
logger.debug("Session successfully tested, use it again.");
}
testChannel.exit();
} catch (Throwable t) {
logger.info("Session terminated. Create a new one.");
session = jsch.getSession(user, host, port);
session.setConfig(config);
session.connect();
}
return session;
}
This version runs several weeks in a productive environment. Once a day I have the info message logged.
The costs of opening a channel and performing some do-nothing-command are somewhat annoying, but I found no other way to be definitely sure about the state of the session.
You can try by invoking the following method before invoking Session#connect().
Session#setServerAliveInterval(int milliseconds)
Although I found one more function Session#sendKeepAliveMsg() which can be tried.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With