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
You can use a pool , I used org.apache.commons.pool2 so the pool is responsible of providing connected sessions, basically:
Above worked for me, also keep in mind that if you add logic on validate, the poolConfig should set true on testOnBorrow or testOnReturn. So I used KeyedObjectPool you should get connections from the pool via borrowObject method and make sure you return them to the pool once you operation is complete via returnObject.
https://commons.apache.org/proper/commons-pool/api-2.2/org/apache/commons/pool2/PooledObjectFactory.html
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.
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.