Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Browser testing is essential if you have a website or web applications that users interact with. Manual testing can be very helpful to an extent, but given the multiple browsers available, not to mention versions and operating system, testing everything manually becomes time-consuming and repetitive.

To help automate this process, Selenium is a popular choice for developers, as an open-source tool with a large and active community. What's more, we can further scale our automation testing by running on theLambdaTest cloud-based testing platform.

Read more through our step-by-step tutorial on how to set up Selenium tests with Java and run them on LambdaTest:

>> Automated Browser Testing With Selenium

Partner – Orkes – NPI EA (cat=Java)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

1. Introduction

In this tutorial, we’re going to take a deeper look into using the JSch library to perform SFTP operations.

In particular, we’ll look at the com.github.mwiede:jsch fork of the original com.jcraft:jsch library, since this is still actively maintained, whereas the original no longer is.

2. Dependencies

To use JSch, we first need to include the latest version in our build, which is 2.27.5 at the time of writing.

If we’re using Maven, we can include this dependency in our pom.xml file:

<dependency>
    <groupId>com.github.mwiede</groupId>
    <artifactId>jsch</artifactId>
    <version>2.27.5</version>
</dependency>

At this point, we’re ready to start using it in our application.

3. Connecting to an SFTP Server

Now that we’ve got JSch set up in our application, we’re ready to connect to our remote service.

Before we can do that, we need to create a new JSch session:

JSch jSch = new JSch();

Session session = jSch.getSession(USERNAME, HOSTNAME, PORT);

This will tell JSch to connect to the SSH server running on the provided host and port, and to connect as the provided username.

We also need to provide a UserInfo instance. This interface helps us handle all the interactive aspects of our SSH connection – including answering any prompts or providing any credentials that might be needed:

session.setUserInfo(new UserInfo() {
    @Override
    public String getPassphrase() {
        return null;
    }

    @Override
    public String getPassword() {
        return null;
    }

    @Override
    public boolean promptPassword(String message) {
        return false;
    }

    @Override
    public boolean promptPassphrase(String message) {
        return false;
    }

    @Override
    public boolean promptYesNo(String message) {
        return false;
    }

    @Override
    public void showMessage(String message) {

    }
});

If we’re building an interactive application, this class will act to pass the prompts to the user. If we’re building a non-interactive one, we can handle the prompts directly ourselves.

At this point, we can attempt to connect to our server:

session.connect();

However, at this point, this will likely fail for a few reasons.

3.1. Host Keys

The first problem we’ll encounter is managing the SSH server host key.

Host keys exist so that the SSH client knows that the server is one it can trust. If the host key exactly matches what’s expected for this server, the connection can proceed. If it doesn’t match, the connection is rejected as unsafe. And if we’ve never connected to the server before, the host key is unknown, and the user needs to decide if it’s safe or not.

If we do nothing to support this, we’ll get a JSchUnknownHostKeyException exception thrown on connecting to our server:

com.jcraft.jsch.JSchUnknownHostKeyException: UnknownHostKey: [localhost]:50022. EDDSA key fingerprint is SHA256:VVDqlx5nL9fqS/Wzq87zX1Ze/FCQEmZKiXk5AV2G2jI

JSch allows us to use the same known_hosts format that other SSH clients use. We can specify one of these to use if we wish:

jSch.setKnownHosts("/users/baeldung/.ssh/known_hosts");

Alternatively, we can configure our UserInfo object to answer the prompts to accept the host key:

@Override
public boolean promptYesNo(String message) {
    if (message.startsWith("The authenticity of host")) {
        return true;
    }

    return false;
}

The exact prompt that we receive will contain the server hostname and port, and the host key itself. We should then do whatever checks we need on these to ensure they’re valid, or we can simply accept any key as shown above.

3.2. Password Authentication

Once our application can trust the SSH server we’re connecting to, we still get an error connecting to our server:

com.jcraft.jsch.JSchException: Auth cancel for methods 'publickey,password,keyboard-interactive'

The next thing we need to be able to support is authentication. The simplest form of this is providing a password for the user we’re connecting as. We can handle this by implementing two more methods in our UserInfo object – promptPassword() and getPassword().

The first of these is to respond to the password prompt, indicating if we’re going to provide a password or not:

@Override
public boolean promptPassword(String message) {
    return true;
}

The message here will indicate the user, host and port that we’re connecting to, so we can decide if we have a password for this connection or not.

The second method to implement is to provide the actual password to use:

@Override
public String getPassword() {
    return "te5tPa55word;
}

At this point, assuming our password is correct, we’ll successfully connect to the server.

3.3. Public/Private Key Authentication

As an alternative to password authentication, we can also use public/private key authentication. As usual with SSH connections, this requires that we’ve already generated our keys and correctly added the public key to our SSH server.

JSch supports RSA, DSA, ECDSA and Ed25519 keys, all of which can be generated by standard SSH tools such as ssh-keygen. The keys themselves can be provided in a variety of formats, including the standard OpenSSH format, PKCS#8, OpenSSL PEM format and PuTTY PPK. Which of these we want to use depends on our exact use cases.

Once we’ve done this, we can configure JSch to know about the private key:

jSch.addIdentity("ssh_keys/id_rsa");

Once we’ve done this, our connection will automatically attempt to use this key to connect to any servers. If the server accepts the key, our connection will be successful.

In some cases, though, our keys need a passphrase to unlock them. We can handle this by implementing the promptPassphrase() and getPassphrase() methods in our UserInfo object:

@Override
public String getPassphrase() {
    return "te5tPa55word";
}

@Override
public boolean promptPassphrase(String message) {
    return true;
}

This works exactly the same as for passwords, only we’re providing the passphrase for our local key instead of for the remote user.

4. SFTP Connections

Once we’ve connected to our SSH server, we can open an SFTP channel. This is done using the Session.openChannel() call:

Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;

If our SSH connection supports SFTP, this will return a ChannelSftp instance that we can use to perform SFTP activities. If not, this will throw a JSchException indicating this.

4.1. Changing Directory

Our SFTP connection maintains an active directory on both the local and remote sides of the connection. These are used for all of the file and directory-based commands that we can perform.

We can determine the current directory using the pwd() and lpwd() methods on the ChannelSftp instance:

String pwd = sftp.pwd();
String lpwd = sftp.lpwd();

The lpwd() method returns the local working directory, whereas the pwd() method returns the current working directory on the remote server.

We can change these using the cd() and lcd() methods:

sftp.cd("/tmp");
sftp.lcd("/tmp");

Once done, all commands will now act based on the new directory instead.

4.2. Listing Files

We can use the ls() method to get a list of all the files and directories on the remote server:

List<ChannelSftp.LsEntry> remoteLs = sftp.ls(".");

This takes a directory to list the files of, which can either be an absolute directory on the server or a directory relative to the current one. If we specify a value of “.”, this will be the current working directory itself.

This will return a list of LsEntry types. These contain the filename within the target directory, and the attributes of the file – including permissions, file size, access dates, and so on:

for (ChannelSftp.LsEntry file : remoteLs) {
    String filename = file.getFilename();
    SftpATTRS attrs = upload.getAttrs();
}

If we know the name of a file or directory, we can also use the stat() method to get the attributes for it directly without needing to list everything:

SftpATTRS attrs = sftp.stat("upload");

If the file or directory exists, this will return the details of it. If it doesn’t, this will throw an SftpException instead to indicate this fact.

Note that there’s no local version of these methods. Since the local version would simply work with files on the local file system, we can already do that with standard Java IO methods.

4.3. Transferring Files

Now that we can connect to our SSH server and discover which files are available, we need to be able to transfer files to and from the server.

We can send files to the remote server using the put() method. We have several variations of this, all of which take the filename to write to, but can provide the actual file contents in different ways:

// Copy the local file to the remote file.
sftp.put("localFile.txt", "remoteFile.txt");

// Send the contents of the input stream to the remote file.
sftp.put(inputStream, "remoteFile.txt");

// Open an output stream onto the remote file.
OutputStream outputStream = sftp.put("remoteFile.txt");

The InputStream version can consume an input stream from any source, and the OutputStream version gives us an output stream that we can write to in any way.

Filenames can either be relative to the appropriate working directory or absolute filenames anywhere on the file system.

We can also transfer in the opposite direction – fetching files from the remote server. We do this using the get() method. Again, we have the equivalent variations of this that we can use:

// Copy the remote file to the local file.
sftp.get("remoteFile.txt", "localFile.txt");

// Send the contents of the remote file to the output stream.
sftp.get("remoteFile.txt", outputStream);

// Open an input stream onto the remote file.
InputStream inputStream = sftp.get("remoteFile.txt");

As we’d expect, the OutputStream version writes the remote file to the output stream, and the InputStream version gives us an input stream to the remote file that we can consume however we wish.

As before, the filenames provided can either be relative to the appropriate working directory absolute filenames anywhere on the appropriate filesystem.

7. Summary

In this article, we took a closer look at the JSch library and how to use it for SFTP operations. There’s more that can be done with this, so next time you need to transfer files between systems, why not give it a try?

As usual, all of the examples from this article are available over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments