Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

sftp

jsch

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;
}
like image 683
Michael Avatar asked Apr 02 '13 15:04

Michael


People also ask

How do I connect to an SFTP server in jsch?

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.

What is a SFTP channel?

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.

How to cancel a channelsftp operation immediately?

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.

How do I connect to an SFTP server?

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.


2 Answers

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.

like image 189
Robert H Avatar answered Nov 16 '22 02:11

Robert H


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());
    }
}
like image 29
Damienknight Avatar answered Nov 16 '22 03:11

Damienknight