When the code below has finished running, netstat -a|grep sftp
shows an open SFTP connection. It also shows up as an open connection in JProfiler.
channel.isConnected()
in the finally block prints false. Any ideas why the connections is not being closed as I'm at a loss?
public static void clean() {
com.jcraft.jsch.ChannelSftp channel = null;
try {
channel = Helper.openNewTLSftpChannel();
channel.connect();
channel.cd(remoteFileDirectory);
List<ChannelSftp.LsEntry> list = channel.ls("*." + fileType);
for (ChannelSftp.LsEntry file : list) {
String fileName = file.getFilename();
DateTime fileDate = new DateTime(parseDateFromFileName(fileName));
//if this file is older than the cutoff date, delete from the SFTP share
if (fileDate.compareTo(cleanupCutoffdate) < 0) {
channel.rm(fileName);
}
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
if (channel != null) {
channel.disconnect();
System.out.println(channel.isConnected());
}
}
}
Adding openNewTLSftpChannel()
below:
public static ChannelSftp openNewSftpChannel(String privateKeyFileName, String password, String username, String host, int port)
throws ConfigurationErrorException {
JSch jsch = new JSch();
File sftpPrivateFile = new File(privateKeyFileName);
Channel channel;
try {
if (!sftpPrivateFile.canRead()) {
throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
}
jsch.addIdentity(sftpPrivateFile.getAbsolutePath(), password);
Session session = jsch.getSession(username, host, port);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
} catch (JSchException jschException) {
throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
}
return (ChannelSftp) channel;
}
JSch dependency is as follows: To connect to an SFTP server, we first need to initialize a JSch object: Any connection between the client and server requires a session. We can create a Session for our connection from the JSch object which we just created: login is the name of the SFTP user.
A Channel connected to an sftp server (as a subsystem of the ssh server). This class supports the client side of the sftp protocol, version 3, and implements an interface similar to the usual sftp command line client. The Sftp class in the examples directory implements a command line client based on this class.
a vector of ChannelSftp.LsEntry objects. List files specified by the remote path . Each files and directories will be passed to LsEntrySelector#select (LsEntry) method, and if that method returns LsEntrySelector#BREAK, the operation will be canceled immediately.
To connect to an SFTP server, we first need to initialize a JSch object: Any connection between the client and server requires a session. We can create a Session for our connection from the JSch object which we just created: login is the name of the SFTP user. hostname is the address of the SFTP server.
If you take a look at the JSCH examples for SFTP you'll see how the session is terminated:
//setup Session here
...
session.connect();
...
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
...run sftp logic...
//close sessions here
sftpChannel.exit();
session.disconnect();
You'll notice that there are two parts to the connection and disconnection; the Session object and the Channel object.
In my code I use the Session object to set my authentication information, and the Channel object to execute the sftp commands I need.
In your instance, you're creating the Session object in your openNewSftpChannel method, but it is never closed, hence your session stays alive.
For further context, check out the examples.
Robert H is correct, you need to exit your channel and disconnect your session. I wanted to add that the session exists even when the channel has been closed. Since you create your session within a try block inside a method, it seems you have lost your session, but you can get it back using 'getSession' on your sftpChannel channel.
You can change your finally block to this:
} finally {
if (channel != null) {
Session session = channel.getSession();
channel.disconnect();
session.disconnect();
System.out.println(channel.isConnected());
}
}
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