Java IO Tutorial

File Transfer using SFTP in Java (JSch)

This article shows how to do file transfer from a remote server to the local system and vice versa, using SSH File Transfer Protocol (SFTP) in Java.

P.S Tested with JSch 0.1.55

1. JSch Dependency

pom.xml

  <dependency>
      <groupId>com.jcraft</groupId>
      <artifactId>jsch</artifactId>
      <version>0.1.55</version>
  </dependency>

2. File Transfer – JSch Examples

2.1 In JSch, we can use put and get to do file transfer between servers.

We use put to transfer files from a local system to the remote server.


channelSftp.put(localFile, remoteFile);

We use get to download files from a remote server to the local system.


channelSftp.get(remoteFile, localFile);

2.2 Password authentication.


  JSch jsch = new JSch();
  jsch.setKnownHosts("/home/mkyong/.ssh/known_hosts");
  jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);

  jschSession.setPassword(PASSWORD);

2.3 Public and private keys authentication, read this Use Public Key Authentication with SSH

  • Local private key – /home/mkyong/.ssh/id_rsa
  • Remote public key – ~/.ssh/authorized_keys

  JSch jsch = new JSch();
  jsch.setKnownHosts("/home/mkyong/.ssh/known_hosts");
  jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);

  jsch.addIdentity("/home/mkyong/.ssh/id_rsa");

2.4 Review this complete JSch example to transfer a file from the local system to a remote server 1.2.3.4, authenticate using an SSH password.

SFTPFileTransfer.java

package com.mkyong.io.howto;

import com.jcraft.jsch.*;

public class SFTPFileTransfer {

    private static final String REMOTE_HOST = "1.2.3.4";
    private static final String USERNAME = "";
    private static final String PASSWORD = "";
    private static final int REMOTE_PORT = 22;
    private static final int SESSION_TIMEOUT = 10000;
    private static final int CHANNEL_TIMEOUT = 5000;

    public static void main(String[] args) {

        String localFile = "/home/mkyong/local/random.txt";
        String remoteFile = "/home/mkyong/remote/afile.txt";

        Session jschSession = null;

        try {

            JSch jsch = new JSch();
            jsch.setKnownHosts("/home/mkyong/.ssh/known_hosts");
            jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);

            // authenticate using private key
            // jsch.addIdentity("/home/mkyong/.ssh/id_rsa");

            // authenticate using password
            jschSession.setPassword(PASSWORD);

            // 10 seconds session timeout
            jschSession.connect(SESSION_TIMEOUT);

            Channel sftp = jschSession.openChannel("sftp");

            // 5 seconds timeout
            sftp.connect(CHANNEL_TIMEOUT);

            ChannelSftp channelSftp = (ChannelSftp) sftp;

            // transfer file from local to remote server
            channelSftp.put(localFile, remoteFile);

            // download file from remote server to local
            // channelSftp.get(remoteFile, localFile);

            channelSftp.exit();

        } catch (JSchException | SftpException e) {

            e.printStackTrace();

        } finally {
            if (jschSession != null) {
                jschSession.disconnect();
            }
        }

        System.out.println("Done");
    }

}

3. JSch Exceptions

Some common exceptions.

3.1 For UnknownHostKey exception, add the remote IP address into the known_hosts file.

Terminal

$ ssh-keyscan -t rsa 1.2.3.4 >> ~/.ssh/known_hosts

3.2 For invalid privatekey, convert the private key to another format.

Terminal

$ ssh-keygen -p -f ~/.ssh/id_rsa -m pem

3.3 For Auth fail, make sure the provided password is correct.

Terminal

com.jcraft.jsch.JSchException: Auth fail
	at com.jcraft.jsch.Session.connect(Session.java:519)
	at com.mkyong.io.howto.SFTPFileTransfer.main(SFTPFileTransfer.java:34)

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-io

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
20 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Manuel Gaytán
2 years ago

Thanks a lot, it was so useful. And as always you explain very clearly. GOD bless you.

Viss
10 months ago

What is timeout needed for 1 GB file transfer

Mohan
1 year ago

How to change/set remote file permission after transfer in sftp

Sanket
1 year ago

Thank you so much for this code. It works perfectly.

Gurpreet Singh
1 year ago

The code works fine when running locally but throws an Unknownhost exception when running an application inside the Kubernetes POD. I did add a known host locally and point to that file with the method setKnownHosts but it doesn’t work inside the POD (even targetting the known host file).

Do we need to install ssh inside Linux based K8 pod with yum install ssh or JSch is independent of that? If yes, what could be the reason for that?

Rohit
1 year ago

is it necessary to set a known host

Nishi
1 year ago

How do we connect if we have the private key as a String value? not in the form of private key file

Chris
1 year ago

Hello,
there is any way to limit to use channel.ls but limited to only first 100 files?

Because if i use channel.ls and have hundred of files, these are locked by that script and i cannot run parallel processes to download simultaneously files.

Thanks

Jimmy
2 years ago

I am successful in using JSch sending a file from local to remote directory but need assistance with sending a mainframe data set where the data set name is surrounded by single quotes. I can send a file to a data set without single quote around the name but not with single quotes around the name and I need to use single quotes.
private String datasetName = “‘ABC.DE.FGHI.KL001′”;

satish kapase
2 years ago

getting this error

java.lang.ArrayIndexOutOfBoundsException: 20480
    at com.jcraft.jsch.Session.connect(Unknown Source)
    at filetransfer.SFTPFileTransfer.main(SFTPFileTransfer.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
com.jcraft.jsch.JSchException: Session.connect: java.lang.ArrayIndexOutOfBoundsException: 20480
    at com.jcraft.jsch.Session.connect(Unknown Source)
    at filetransfer.SFTPFileTransfer.main(SFTPFileTransfer.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Done

created jar and running on local machin

Ketan
2 years ago

Hi

When I am trying to work with Executor service by creating multiple threads some files are not getting uploaded and I am receiving below error. Can you please help me.

4: 
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2362)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
at com.test.filesystemservice.CopyFileTask.run(CopyFileTask.java:45)
at com.test.filesystemservice.ParallelTasks.lambda$1(ParallelTasks.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Abhay
2 years ago
Reply to  Ketan

Did you figure out the root cause &/or solution?

Devendra goyal
2 years ago

In my case sftp Exception:Algorithm negotiation fail

 JSch js = new JSch();
  Session s = js.getSession(username, hostname, 22);
  s.setPassword(password);
  Properties confignn = new Properties();
  confignn.put(“StrictHostKeyChecking”, “no”);
  s.setConfig(confignn);
  s.connect();

Last edited 2 years ago by Devendra goyal
Simone
2 years ago
Reply to  Devendra goyal

Have you solved this? Same error for me 🙁

Alexandre Silva
2 years ago

Good afternoon,

Would I be able to transfer a directory, its subdirectories and all existing files at once?

Saran
2 years ago

Jsch supports only one file transfer mode – binary. But how does camel sftp support ascii/binary file transfer modes? Camel sftp also internally uses jsch right?

Bennett
3 years ago

good tutorial

Madhu Sagar
3 years ago

When I give password it works fine, but when I try for SSH public key
like this — jsch.addIdentity(“~/.ssh/authorized_keys”);

Error occurred due to com.jcraft.jsch.JSchException: java.io.FileNotFoundException: C:\Users\****\.ssh\authorized_keys (The system cannot find the file specified)

May I know why its referring to local path instead of remote server