How do I connect to an SSH server using JSch?

To connect to an SSH server using JSch (Java Secure Channel), you need to perform the following steps:

Steps to Connect to SSH Server Using JSch

  1. Add the JSch library to your project dependencies.
    • If using Maven, add the following dependency:
    <dependency>
        <groupId>com.jcraft</groupId>
        <artifactId>jsch</artifactId>
        <version>0.1.55</version>
    </dependency>
    
    • If not using a dependency manager, download jsch.jar and add it to your project’s classpath.
  2. Write the code to establish an SSH connection. Here is an example code snippet:

package org.kodejava.jsch;

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

public class SSHConnectionExample {
    public static void main(String[] args) {
        String host = "example.com"; // Replace with SSH server address
        String username = "username";  // Replace with username
        String password = "password";  // Replace with password
        int port = 22; // Default SSH port

        JSch jsch = new JSch();

        Session session = null;
        try {
            // Create Session object
            session = jsch.getSession(username, host, port);

            // Set password
            session.setPassword(password);

            // Configure session to avoid asking for key confirmation
            session.setConfig("StrictHostKeyChecking", "no");

            // Connect to the server
            System.out.println("Connecting to " + host);
            session.connect();
            System.out.println("Connected successfully!");

            // Your code to execute commands or perform actions can go here.

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isConnected()) {
                session.disconnect();
                System.out.println("Disconnected from server.");
            }
        }
    }
}

Explanation

  1. JSch Instance:

    • Create an instance of JSch.
  2. Session:
    • Use the jsch.getSession method to create a session object with the necessary credentials: host, username, and port.
  3. Set Password:
    • Use the setPassword method to provide the SSH server password.
  4. Disable Strict HostKey Checking (Optional):
    • By default, JSch checks the host key of the server during the first connection. You can disable this check using:
    session.setConfig("StrictHostKeyChecking", "no");
    
  • Note: Disabling this for production environments can reduce security, so use it cautiously.
    1. Connect:
      • Call session.connect() to establish the SSH connection.
    2. Perform Actions:
      • After connecting, you can now execute commands on the server using a Channel.
    3. Clean Up:
      • Always disconnect the session when done using the session.disconnect() method.

Example with Command Execution

If you want to execute a remote command on the server after connecting:

package org.kodejava.jsch;

import com.jcraft.jsch.*;

import java.io.InputStream;

public class ExecuteSSHCommand {
    public static void main(String[] args) {
        String host = "example.com";
        String username = "username";
        String password = "password";
        int port = 22;

        JSch jsch = new JSch();

        Session session = null;
        Channel channel = null;
        try {
            // Create session and set credentials
            session = jsch.getSession(username, host, port);
            session.setPassword(password);

            // Disable strict host key checking
            session.setConfig("StrictHostKeyChecking", "no");

            // Connect to the server
            System.out.println("Connecting to " + host);
            session.connect();
            System.out.println("Connected successfully!");

            // Open a shell/channel to execute a command
            channel = session.openChannel("exec");

            // Specify the command you want to execute
            ((ChannelExec) channel).setCommand("ls -la");

            // Capture the command's output
            InputStream input = channel.getInputStream();
            channel.connect();
            System.out.println("Command executed!");

            // Read and print the command output
            byte[] buffer = new byte[1024];
            int read;
            while ((read = input.read(buffer)) > 0) {
                System.out.print(new String(buffer, 0, read));
            }

            input.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
            System.out.println("Disconnected from server.");
        }
    }
}

Tips

  • Replace placeholders like example.com, username, and password with actual credentials.
  • Always handle exceptions to prevent runtime crashes.
  • In production setups, manage SSH key authentication instead of plain passwords for enhanced security.

How do I mail merge Word document in Java?

The following example will show you how to use the E-iceblue‘s free Spire.Doc for Java to perform mail merge operations on MS Word documents.

Create Maven Project and Add Dependencies

Create a maven project and add the following dependencies and repositories in your project’s pom.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    ...
    ...

    <dependencies>
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.doc.free</artifactId>
            <version>5.2.0</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>
</project>

Create Mail Merge Template in Microsoft Word

  • Create a new Word document.
  • Place your cursor where you want to add a merge field.

MS Word Mail Merge Template

  • Click the Insert menu, Quick Parts, Fields…
  • In the Field names select MergeField and enter the field name and press OK.

Merge Field

  • To create merge field for image you need to prefix the field name with Image:
  • When finished save the document.

The Mail Merge Code Snippet

The code snippet reads the mail merge template from a file called Receipt.docx. For the image we use a duke.png. Both of these files must be placed in the /src/main/resources directory in your maven project so that the code can read it.

package org.kodejava.example.spire;

import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.reporting.MergeImageFieldEventArgs;
import com.spire.doc.reporting.MergeImageFieldEventHandler;

import java.awt.Dimension;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MailMergeExample {
    public static final Locale LOCALE = new Locale("id", "ID");
    public static final DateFormat DATE_FORMAT = new SimpleDateFormat("dd-MMMM-yyyy", LOCALE);
    public static final NumberFormat NUMBER_FORMAT = NumberFormat.getCurrencyInstance(LOCALE);

    public static void main(String[] args) {
        String[] fieldNames = new String[]{
                "academicYear",
                "registrationNumber",
                "fullName",
                "gender",
                "telephone",
                "address",
                "paymentAmount",
                "inWords",
                "paymentDate",
                "receivedBy",
                "picture"
        };
        String[] fieldValues = new String[]{
                "2021/2022",
                "0001/REG/2021",
                "Foo Bar",
                "M",
                "081234567890",
                "Sudirman Street 100",
                NUMBER_FORMAT.format(1575000),
                "One Million Five Hundred Seventy Five Thousand",
                DATE_FORMAT.format(new Date()),
                "John Doe",
                "/duke.png"
        };

        try {
            Document document = new Document();
            document.loadFromStream(MailMergeExample.class.getResourceAsStream("/Receipt.docx"), FileFormat.Auto);
            document.getMailMerge().MergeImageField = new MergeImageFieldEventHandler() {
                @Override
                public void invoke(Object o, MergeImageFieldEventArgs field) {
                    field.setPictureSize(new Dimension(66, 88));

                    String path = field.getImageFileName();
                    if (path != null && !path.isEmpty()) {
                        try {
                            field.setImage(MailMergeExample.class.getResourceAsStream(path));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            document.getMailMerge().execute(fieldNames, fieldValues);

            String fileName = "Receipt.pdf";
            FileOutputStream fos = new FileOutputStream(fileName);
            document.saveToStream(fos, FileFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Running the code will create a file called Receipt.pdf with the content as shown in the image below.

Mail Merge Result Document

How do I generate random alphanumeric strings?

The following code snippet demonstrates how to use RandomStringGenerator class from the Apache Commons Text library to generate random strings. To create an instance of the generator we can use the RandomStringGenerator.Builder() class build() method. The builder class also helps us to configure the properties of the generator. Before calling the build() method we can set the properties of the builder using the following methods:

  • withinRange() to specifies the minimum and maximum code points allowed in the generated string.
  • filteredBy() to limits the characters in the generated string to those that match at least one of the predicates supplied. Some enum for the predicates: CharacterPredicates.DIGITS, CharacterPredicates.LETTERS.
  • selectFrom() to limits the characters in the generated string to those who match at supplied list of Character.
  • usingRandom() to overrides the default source of randomness.

After configuring and building the generator based the properties defined, we can generate the random strings using the generate() methods of the RandomStringGenerator. There are two methods available:

  • generate(int length) generates a random string, containing the specified number of code points.
  • generate(int minLengthInclusive, int maxLengthInclusive) generates a random string, containing between the minimum (inclusive) and the maximum (inclusive) number of code points.

And here is your code snippet:

package org.kodejava.commons.text;

import org.apache.commons.text.CharacterPredicates;
import org.apache.commons.text.RandomStringGenerator;

public class RandomStringDemo {
    public static void main(String[] args) {
        RandomStringGenerator generator = new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.DIGITS, CharacterPredicates.LETTERS)
                .build();

        for (int i = 0; i < 10; i++) {
            System.out.println(generator.generate(10, 20));
        }
    }
}

Below are examples of generated random alphanumeric strings:

weJDtVARLIFS96WXje
FYrNzTR3Q3dUrLT3Xsc
4F1fu8nSsA
nIQi3a4Oyv9
l6QcsP9bejdbaLd2jd
Cc9YgTfgwo
2B8un8YCcxn9m2
RAN2dZAWalUIWeZeoS
jPQspicyaKfAzS14twH
GTurc0lWkSid03rG0JZ

Apache Logo

Maven Dependencies

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.12.0</version>
</dependency>

Maven Central

How do I define access modifiers in Lombok’s @Getter and @Setter annotations?

By default, when we use the Lombok’s @Getter and @Setter annotations the getters and setters will be created with public access modifier. We can however change the access modifier by setting the AccessLevel of the @Getter and @Setter annotations. The available choices for the access level are AccessLevel.PUBLIC, AccessLevel.PROTECTED, AccessLevel.PACKAGE, AccessLevel.PRIVATE. These enum values correspond to Java’s access modifier. While the AccessLevel.NONE will disable the getter and setter method generation.

package org.kodejava.lombok.support;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Person {
    @Setter(AccessLevel.PROTECTED)
    private String firstName;

    private String lastName;
    private String gender;

    @Getter(AccessLevel.PRIVATE)
    private int age;
}

How we use the Person class show in the snippet below:

package org.kodejava.lombok;

import org.kodejava.lombok.support.Person;

public class PersonDemo {
    public static void main(String[] args) {
        Person person = new Person();
        person.setLastName("Bar");
        person.setGender("M");
        person.setAge(20);

        System.out.println(person.getFirstName());
        System.out.println(person.getLastName());
        System.out.println(person.getGender());
    }
}

If we try to see the generated class of the Person class we can run the following command to disassemble the class.

javap -p -cp . org.kodejava.lombok.support.Person

And we got the following output of the javap command. As we can see that the setFirstName() method have a protected access modifier and the getAge() method have a private access modifier. The other mutator and accessor method all set to public access modifier.

public class org.kodejava.lombok.support.Person {
    private java.lang.String firstName;
    private java.lang.String lastName;
    private java.lang.String gender;
    private int age;
    public org.kodejava.lombok.support.Person();
    public java.lang.String getFirstName();
    public java.lang.String getLastName();
    public java.lang.String getGender();
    public void setLastName(java.lang.String);
    public void setGender(java.lang.String);
    public void setAge(int);
    protected void setFirstName(java.lang.String);
    private int getAge();
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.28</version>
    </dependency>
</dependencies>

Maven Central

How do I generate getters and setters with Lombok?

The following code snippet show you how to use Project Lombok‘s @Getter and @Setter annotations to generate getters and setters method in your POJO (plain old java objects) classes. Using these annotations remove the need to manually implements the mutator and accessor methods. Although most IDE allows you to generate these methods, using Lombok makes your classes look cleaner, especially when you have a long list of fields.

Here is a simple User class with a handful fields. We will use the @Getter and @Setter annotations on the class level. This will generate the getters and setters method for any non-static fields in the class.

package org.kodejava.lombok.support;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDate;

@Getter
@Setter
public class User {
    private Long id;
    private String username;
    private String password;
    private LocalDate lastLogin;
    private boolean active;
}

Each fields in the class will have its corresponding getter and setter. For example the username field will have the getUsername() and setUsername() method. If the field type is boolean such as active it will generate the method setActive() and isActive() method.

Because the accessor and mutator already handled by Lombok, we can use the User class as if we manually implement the getters and setters method.

package org.kodejava.lombok;

import org.kodejava.lombok.support.User;

import java.time.LocalDate;

public class UserDemo {
    public static void main(String[] args) {
        User user = new User();
        user.setId(1L);
        user.setUsername("foo");
        user.setPassword("secret");
        user.setLastLogin(LocalDate.now());
        user.setActive(true);

        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getLastLogin());
        System.out.println(user.isActive());
    }
}

If for some reasons you want to disable the getter and setter on specific field, or you want the change the access level, you can use the AccessLevel enums value for the @Getter and @Setter annotations. For example in the code snippet below the username will have no getter and setter while the lastLogin getter and setter will have protected access modifier. The AccessLevel enums includes PUBLIC, MODULE, PROTECTED, PACKAGE, PRIVATE and NONE.

package org.kodejava.lombok.support;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDate;

@Getter
@Setter
public class User {
    private Long id;
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private String username;
    private String password;
    @Getter(AccessLevel.PROTECTED)
    @Setter(AccessLevel.PROTECTED)
    private LocalDate lastLogin;
    private boolean active;
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.28</version>
    </dependency>
</dependencies>

Maven Central