Why does an SFTP connection still exist after the JSCH Channel has been closed?

Michael picture Michael · Apr 2, 2013 · Viewed 27.6k times · Source

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;
}

Answer

Robert H picture Robert H · Apr 2, 2013

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.