Sending Files via FTP From Your Java Applications - Part 2 of 2 - Using Jsch for SFTP

Yesterday I introduced how I send files via FTP and SFTP from my java applications. In that post I showed you how to use the Jakarta Commons Net package to FTP files. Today I will show you how to use the JSch (Java Secure Channel) library to do SFTP transfers.



Part 2 of 2 - Using JSch (Java Secure Channel)
First off, what exactly is JSch? Well, the JCraft team describes it says that "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." Personally, I’ve only used it to SFTP files, and have not yet used any of its other features.

To use JSch, you’ll first want to download the appropriate libraries from JCraft. Click here to be taken to the JSch homepage and download the jsch library. For my example I downloaded the jsch-0.1.32.jar file directly from their site. Once you download the file, put it in your classpath.

Now just grab the code I present below and go to town. Like the Commons Net library, the JSch library is extremely easy to use!

package com.tima.examples;

import com.jcraft.jsch.*;
import java.io.*;
import java.util.*;

/**
 * This class is used to demonstrate the usage of the
 * JCraft JSch package to SFTP files.
 * 
 * @author  Tim Archer 04/20/07
 * @version $Revision: 1.1 $
 */
public class TestJSch {
    
    /** Creates a new instance of TestCommonsNet */
    public TestJSch() {
    }
    
    /**
     * main - Unit test program
     * @param args Command line arguments
     *
     */
    public static void main(String args[]) {
        try {
            String ftpHost = "ftp.myserver.com";
            int ftpPort = 22;
            String ftpUserName = "tima";
            String ftpPassword = "mypassword";
            String ftpRemoteDirectory = "/home/tarcher/tmp/";
            String fileToTransmit = "c:\\temp\\test.txt";
            
            //
            //First Create a JSch session
            //
            System.out.println("Creating session.");
            JSch jsch = new JSch();
            Session session = null;
            Channel channel = null;
            ChannelSftp c = null;

            //
            //Now connect and SFTP to the SFTP Server
            //
            try {
                //Create a session sending through our username and password
                session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
                System.out.println("Session created.");    
                session.setPassword(ftpPassword);
                //Security.addProvider(new com.sun.crypto.provider.SunJCE());
    
                //
                //Setup Strict HostKeyChecking to no so we dont get the 
                //unknown host key exception
                //
                java.util.Properties config = new java.util.Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config);
                session.connect();
                System.out.println("Session connected.");
    
                //
                //Open the SFTP channel
                //
                System.out.println("Opening Channel.");
                channel = session.openChannel("sftp");
                channel.connect();
                c = (ChannelSftp)channel;
            } catch (Exception e) {
                System.err.println("Unable to connect to FTP server. "+e.toString());
                throw e;
            }            
            
            //
            //Change to the remote directory
            //
            System.out.println("Changing to FTP remote dir: " + ftpRemoteDirectory);
            c.cd(ftpRemoteDirectory);            
            
            //
            //Send the file we generated
            //  
            try {
                File f = new File(fileToTransmit);
                System.out.println("Storing file as remote filename: " + f.getName());
                c.put(new FileInputStream(f), f.getName());
            } catch (Exception e) {
                System.err.println("Storing remote file failed. "+e.toString());
                throw e;
            }
            
            //
            //Get the list of files in the remote server directory
            //
            Vector files = c.ls(ftpRemoteDirectory);
            
            //
            //Log if we have nothing to download
            //
            if (files.size() == 0) {
                System.out.println("No files are available for download.");
            }
            //
            //Otherwise download all files except for the . and .. entries
            //
            else {
                for (int i=0; i<files.size(); i++) {
                    com.jcraft.jsch.ChannelSftp.LsEntry lsEntry = (com.jcraft.jsch.ChannelSftp.LsEntry) files.get(i);
                    
                    if (!lsEntry.getFilename().equals(".") && !lsEntry.getFilename().equals("..")) {
                        System.out.println("Downloading file "+lsEntry.getFilename());
                        
                        String outputFileName = "c:\\temp\\"+lsEntry.getFilename();
                        
                        //Get the write and write it to our local file system
                        File f = new File(outputFileName);                    
                        c.get(lsEntry.getFilename(), new FileOutputStream(f));

                        //
                        //Remove the file from the server
                        //    
                        /*
                        c.rm(lsEntry.getFilename());
                        */
                    }
                }
            }
            
            //
            //Disconnect from the FTP server
            //
            try {
                c.quit();
            } catch (Exception exc) {
                System.err.println("Unable to disconnect from FTP server. " + exc.toString());
            }            
                        
        } catch (Exception e) {
            System.err.println("Error: "+e.toString());
        }
        
        System.out.println("Process Complete.");
        System.exit(0);
    }    
}

Like my Commons Net example, this post shows a very simple example of using the JSch library to perform various SFTP actions. Take some time to study the main method in the example above and I think you’ll find it very easy to follow. Specifically, it will show you how to:

  • Connect to an SFTP server
  • Change to a new remote directory
  • Set the transfer mode
  • Upload a file
  • Get a list of files in the remote directory and download a file.
  • Disconnect from the SFTP server.

This now brings us to the end of my two part series on FTP’ing files from your java applications. Now I need to go think up a post for tomorrow. For now, happy FTP'ing!



Comments

Thank you very much for

Thank you very much for extremely useful blog Tim. I've been looking for a tutorial as exactly same as yours. It really helped. Thanks again.

Thanks very much for this

Thanks very much for this example. It is the first thing I've come across (and I've been searching for a while) that gives a very basic rundown of how to upload via SFTP. By any chance could you give a briefing, or possibly point me in the right direction of how to add private key authentication to login to a server as well? Again many thanks!

Hi Garrett. I have not yet

Hi Garrett. I have not yet tried to use private key authentication to login to a server through a Java program.

It does look like the JSch library may support key based authentication though through a quick browse of their homepage. It also looks like their "examples" folder may contain something that operates using keys.

don't

don't forget

session.disconnect();

Excellent recommendatiom and example

I was just assigned this task at work. I started researching some different ways of doing SFTP with Java. Some forums had all kinds of non-elegant solutions.

Luckily, I found your page and my task was easy as pie.

Thanks for recommending Jsch and taking the time to put out a nice, clean documented example.

I appreciate it.

v2.0