Transferring a File Through SFTP in Quarkus

Lionel P. Albus
4 min readJan 23, 2021

In this tutorial we’ll discuss how to download and upload files from a remote server using SFTP in Quarkus.

we’ll use two different libraries: JSch and Quarkus JSch.

  1. Using JSch

First, let’s see how to download and upload files from a remote server using the JSch library.

1.1 Maven Configuration

We’ll need to add the jsch dependency to our pom.xml. The latest version of jsch can be found on Maven Central.

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

1.2 Add — initialize-at-run-time to application.properties

When using JSch library we’ll need to add a class com.jcraft.jsch to initialize at run time. If we’ll forget to add this class when we’ll build a native image we’ll get an error to follow the message below.

com.oracle.svm.core.util.UserError$UserException: No instances of java.net.Inet4Address are allowed in the image heap as this class should be initialized at image

quarkus.native.additional-build-args=--initialize-at-run-time=com.jcraft.jsch,-H:+TraceClassInitialization

2. Using Quarkus JSch

First, let’s see how to download and upload files from a remote server using the quarkus-jsch library.

2.1 Maven Configuration

We’ll need to add the quarkus-jsch dependency to our pom.xml. The latest version of jsch can be found on Maven Central.

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jsch</artifactId>
</dependency>

3. Downloading a File With JSch or Quarkus JSch

Now, We’ll set up JSch or Quarkus JSch. JSch or Quarkus JSch enables us to use either password authentication or public key authentication to access a remote server. In the example, we’ll use password authentication.

public static ByteArrayOutputStream getSFTPFile(String filePath, String fileName) {
Session jschSession = null;
try {
// Setting up JSch or Quarkus JSch
JSch jsch = new JSch();
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
// authenticate using password
jschSession.setPassword(PASSWORD);
jschSession.setConfig("StrictHostKeyChecking", "no");

// 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
InputStream is = channelSftp.get(filePath + fileName);
ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(is, output);

channelSftp.exit();

ByteArrayOutputStream var11 = output;
return var11;
} catch (Exception e) {
log.error("error ftp", e);
} finally {
if (jschSession != null) {
jschSession.disconnect();
}
}
return null;
}

In the example above, the remoteHost represents the name or IP address of the remote server (i.e. example.com). We can define the variables used in the test as:

private static final String REMOTE_HOST = "HOST_NAME_HERE";
private static final String USERNAME = "USERNAME_HERE";
private static final String PASSWORD = "PASSWORD_HERE";
private static final int REMOTE_PORT = 22;
// REMOTE_PORT_HERE
private static final int SESSION_TIMEOUT = 10000;
// SESSION_TIMEOUT_HERE
private static final int CHANNEL_TIMEOUT = 5000;
// CHANNEL_TIMEOUT_HERE

In the example method getSFTPFile() above, we can also download a file from the remote server using ChannelSftp.get(). The filePath represents the path of the target local directory follow the example code below.

String filePath = "src/main/resources/files/"; 
String fileName = "sftpFile.txt";
ByteArrayOutputStream file = getSFTPFile(filePath, fileName);

4. Uploading a File With JSch and Quarkus JSch

Now, We’ll set up JSch and Quarkus JSch. JSch and Quarkus JSch enables us to use either password authentication or public key authentication to access a remote server. In the example, we’ll use password authentication.

public static Boolean putSFTPFile(String fileName, ByteArrayOutputStream outputStream) {
Session jschSession = null;
try {
// Setting up JSch or Quarkus JSch
JSch jsch = new JSch();
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
// authenticate using password
jschSession.setPassword(PASSWORD);
jschSession.setConfig("StrictHostKeyChecking", "no");

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

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

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

ChannelSftp channelSftp = (ChannelSftp) sftp;
String remoteFile = "/home/sftp/in/";
// transfer file from local to remote server
channelSftp.put(new ByteArrayInputStream(outputStream.toByteArray()), remoteFile + fileName);

channelSftp.exit();

return true;
} catch (Exception e) {
log.error("error ftp", e);
} finally {
if (jschSession != null) {
jschSession.disconnect();
}
}
return false;
}

In the example above, the remoteHost represents the name or IP address of the remote server (i.e. example.com). We can define the variables used in the test as:

private static final String REMOTE_HOST = "HOST_NAME_HERE";
private static final String USERNAME = "USERNAME_HERE";
private static final String PASSWORD = "PASSWORD_HERE";
private static final int REMOTE_PORT = 22;
// REMOTE_PORT_HERE
private static final int SESSION_TIMEOUT = 10000;
// SESSION_TIMEOUT_HERE
private static final int CHANNEL_TIMEOUT = 5000;
// CHANNEL_TIMEOUT_HERE

In the example method putSFTPFile() above, we can also upload a file from the remote server using ChannelSftp.put(). The filePath represents the path of the target local directory follow the example code below.

Boolean status = putSFTPFile("sample.txt", outputStream);
// In this example method putSFTPFile() requires a file of type ByteArrayOutputStream.

you can see our code here Lionel-P-Albus/quarkus-sftp

Thanks, everyone for reading if you have any questions please comment. The last one I’m sorry about my English language if I’m using the wrong word please recommend to me. 👏👏👏

--

--