Comparing Java SSH APIs: Jsch vs Maverick Synergy

JSch is a popular Java library for SSH and SFTP, but as applications grow more complex, developers might look for more robust and feature-rich alternatives like Maverick Synergy. Maverick Synergy offers a modern, comprehensive API for SSH, SFTP, and SCP, with a focus on performance, security, scalability and usability.

Jsch?

The JSch API (Java Secure Channel) was created by Atsuhiko Yamanaka and has been widely used since its inception in the early 2000s. It provides a Java-based implementation of SSH (Secure Shell), allowing developers to create secure connections, execute remote commands, and transfer files using SFTP or SCP. With it’s liberal open-source BSD style license, JSch gained popularity for being lightweight and open-source, making it a go-to solution for Java developers needing SSH functionality. Despite its success, JSch has faced criticism for limited feature support and infrequent updates, which has led many developers to explore more modern and comprehensive alternatives.

Maverick Synergy

The Maverick Synergy SSH API, developed by Jadaptive, was introduced to provide a robust and feature-rich solution for secure communications in Java. Building on previous generations of SSH API Maverick Synergy has evolved to offer extensive support for SSH, SFTP, SCP, and public-key authentication. Over time, it has become a favored choice for enterprises seeking high-performance, secure, and scalable SSH implementations. With regular updates and ongoing improvements, Maverick Synergy has positioned itself as a comprehensive tool for developers needing advanced SSH functionalities, offering enhanced security features, better performance, and native compilation support.

This article compares JSch and Maverick Synergy APIs, showing how to migrate from JSch to Maverick Synergy with side-by-side code examples for key SSH operations.


1. Connecting an SSH Client

In both JSch and Maverick Synergy, establishing a connection is the first step in any SSH operation.

JSch Example:

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class JSchExample {
    public static void main(String[] args) throws Exception {
        JSch jsch = new JSch();
        Session session = jsch.getSession("username", "host", 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        System.out.println("Connected with JSch");
    }
}

Maverick Synergy Example:

import com.sshtools.client.SshClient;
import com.sshtools.client.SshClientBuilder;

public class MaverickExample {
    public static void main(String[] args) throws Exception {
        SshClient ssh = SshClientBuilder.create()
                    .withHostname("localhost")
                    .withPort(22)	  
                    .withUsername("root")
                    .build()
        System.out.println("Connected with Maverick Synergy");
    }
}

2. Authenticating with a Password

Password-based authentication is common for simple SSH setups. Here’s how to authenticate with a password in both libraries.

JSch Example:

session.setPassword("your_password");
session.connect();

Maverick Synergy Example:

ssh.authenticate(new PasswordAuthenticator("xxxxxxx"), 10000L);

3. Authenticating with a Public Key

Public key authentication is often preferred for enhanced security.

JSch Example:

jsch.addIdentity("/Users/lee/.ssh/id_rsa");
session.connect();

Maverick Synergy Example:

import com.sshtools.client.IdentityFileAuthenticator;

ssh.authenticate(new IdentityFileAuthenticator(
	Arrays.asList(Paths.get("/Users/lee/.ssh/id_rsa")), (keyinfo)->{
		System.out.println(keyinfo);
		return new String(System.console().readPassword("Passphrase: "));
}), 30000L);

4. Uploading a File via SFTP

SFTP is a secure file transfer protocol built into SSH.

JSch Example:

import com.jcraft.jsch.ChannelSftp;
import java.io.FileInputStream;

ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
FileInputStream fis = new FileInputStream("local_file.txt");
sftpChannel.put(fis, "remote_file.txt");
sftpChannel.disconnect();

Maverick Synergy Example:

Maverick Synergy provides a high-level API for transferring files on the SshClient interface. Use this for simple transfers using java.io.File.

ssh.putFile(new File("local_file.txt")); 

For streaming and a more feature rich SFTP client, use the SftpClient to transfer files. See our Documentation for more information.

import com.sshtools.client.SftpClient;
import com.sshtools.client.SftpClientBuilder;

SftpClient sftp = SftpClientBuilder.create()
		.withClient(ssh)
		.build();

FileInputStream fis = new FileInputStream("local_file.txt");
sftp.put(fis, "local_file.txt");

5. Uploading a File via SCP

SCP is another method for securely transferring files over SSH.

JSch Example:

JSch doesn’t have built-in support for SCP, so developers typically implement SCP over an SSH channel. To keep this article concise we have not included the full code, you can find similar solution here.

import java.io.OutputStream;

ChannelExec execChannel = (ChannelExec) session.openChannel("exec");
execChannel.setCommand("scp -t remote_file.txt");
OutputStream out = execChannel.getOutputStream();
execChannel.connect();
// SCP file transfer logic goes here
execChannel.disconnect();

Maverick Synergy Example:

Maverick Synergy offers native SCP support, making it easier to use.

import com.sshtools.scp.ScpClient;
import java.io.FileInputStream;

ScpClient scp = client.openScpClient();
FileInputStream fis = new FileInputStream("local_file.txt");
scp.put(fis, "remote_file.txt");
scp.close();

6. Executing a Command

Executing remote commands via SSH is a common use case for automation.

JSch Example:

import com.jcraft.jsch.ChannelExec;
import java.io.InputStream;

ChannelExec execChannel = (ChannelExec) session.openChannel("exec");
execChannel.setCommand("ls -la");
InputStream in = execChannel.getInputStream();
execChannel.connect();
// Read the command output from InputStream
execChannel.disconnect();

Maverick Synergy Example:

Again, here Maverick Synergy proves its Enterprise credentials, providing many more methods to support command execution.

You can use the high-level API on SshClient to execute simple commands. These block and return after the command has completed, returning the output of the command as a String.

ssh.executeCommand("ls -la"));

You can use the Task API to submit more complicated tasks.

Task t = CommandTaskBuilder.create()
	.withClient(ssh)
	.withCommand("ls -la")
	.withAutoConsume(false)
	.onTask((task, session)->{
		IOUtils.copy(session.getInputStream(), System.out);
	})
	.build();
			
ssh.addTask(t);
t.waitFor(60000L);

7. Scripting a Shell

Interacting with an SSH shell session is useful for running multiple commands interactively. However, within the SSH protocol the shell is a single stream of data so its difficult to capture the output of individual commands or know if they completed successfully or not.

If you just require a sequence of commands you can do this by separating the commands with EOL, or can use bash operators to execute commands on a single line.

JSch Example:

import com.jcraft.jsch.ChannelShell;
import java.io.OutputStream;

ChannelShell shellChannel = (ChannelShell) session.openChannel("shell");
OutputStream out = shellChannel.getOutputStream();
shellChannel.connect();
// Write to the shell
out.write("pwd\n".getBytes());
out.flush();

Maverick Synergy Example:

Task t = ShellTaskBuilder.create()
	.withClient(ssh)
	.withAutoConsume(false)
	.onTask((task, session)->{
		session.getOutputStream().write("pwd\nexit\n".getBytes());
		IOUtils.copy(session.getInputStream(), System.out);
	})
	.build();
			
ssh.addTask(t);
t.waitFor(60000L);

Again, this is where Maverick Synergy’s Enterprise credentials come into play. Maverick Synergy includes a wrapper implementation called ExpectShell that makes using the shell much easier. Allowing the output of each command to be seprated into a separate process object, providing streams for just that commands output. It also can detect sudo password prompts if you need to execute priviledged operations in a setup that requires a password confirmation to perform.

In this example, we replicate the example above, but instead wrap the task in the ExpectShell so we can execute the commands programatically and process the result or output accordingly.

Task t = ShellTaskBuilder.create()
		.withClient(ssh)
		.withAutoConsume(false)
		.onTask((task, session)->{
			ExpectShell shell = new ExpectShell(task);
			ShellProcess process = shell.executeCommand("pwd");
			IOUtils.copy(process.getInputStream(), System.out);
			shell.exit();
		})
	.build();
			
ssh.addTask(t);
t.waitFor(60000L);

Conclusion

Migrating from JSch to Maverick Synergy can bring significant benefits, including better performance, ease of use, and additional features like native SCP support. The above examples demonstrate how you can perform common SSH tasks with both APIs, helping you smoothly transition your SSH, SFTP, and SCP implementations from JSch to Maverick Synergy.