Blog

Send email with Java: SMTP or email API

Amy Elliott Amy Elliott
· 19 min read · Tips and resources · April 28th, 2025
Java might be your go-to language thanks to its popularity for backend development. And if Java is your programming love language, you’re in luck because it’s also a solid choice for sending emails.

Java’s influence has touched some of the world’s biggest organizations—Amazon, Instagram, eBay and Spotify, to name a few. And since Java has a pretty mature ecosystem, you’re spoiled for choice when it comes to well-established libraries for email sending.

In this tutorial, we’ll cover sending emails with SMTP using Java libraries like Jakarta Mail, Spring Mail and Simple Java Email—plus, we’ll explain how to send your messages through an email API. Let’s get started.

Methods for sending emails with Java

Since there are a number of good options for sending emails with Java, let’s do a quick comparison of the main methods. 

Jakarta Mail

Spring Email

Apache Commons Email

Simple Java Mail

Third-party API (like MailerSend)

Usability

Moderate, boilerplate-heavy

Easy if using Spring

Easy

Very easy, fluent API

Very easy, HTTP + SDKs

Dependencies

Low

Requires Spring Boot

Low

Moderate

Depends on provider

Embedded images

Yes

Yes

Yes

Yes

Yes

Support for HTML & attachments 

Yes

Yes

Yes

Yes

Yes

Template support

No built-in support, can work alongside a template engine to inject HTML

No built-in support but integrates well with template engines

No built-in support, can work alongside a template engine to inject HTML

No built-in support, but allows using strings from template engines for HTML body

Yes, supports built-in dynamic templates

Support for DKIM and S/MIME

Manual configuration

Manual configuration

No

Yes

Yes, may vary by provider

SMTP

Yes

Yes

Yes

Yes

Yes, may vary by provider

REST API

No

No

No

No

Yes

Analytics/monitoring

None

None

None

None

Built-in features and dashboards

Scalability

Good

Good

Moderate

Good

Excellent

Which method should I use?

It depends on the type of project, necessary features, flexibility, budget, and how simple or complex you estimate your email system to be. 

Jakarta Mail: Good for full control and flexibility, custom mail apps/backend, and if you don’t mind its verbose nature.  

Spring email: Best for Spring-based projects.

Apache Commons Email: Good if you need to set up very quickly and only need to send simple emails, like sending from a contact form. 

Simple Java Email: Good for modern apps focused on email or newsletter sending.

Third-party API: Best if you need high deliverability, scalability, and built-in features like analytics or templates for transactional emails, SaaS, e-commerce, etc.

This article will go through how to start sending with the SMTP methods as well as with a third-party API. We’ll use MailerSend’s SMTP relay, email API and Java SDK, and give some code examples to show you how it works. 

Aside from easy integration, a third-party service gives you tons of built-in features that make sending and managing transactional messages simple. With a bit of tweaking and customization to your code, you can get inbound message processing, SMS, templates, tracking, and more out of the box. And best of all, no painful server maintenance is required. I know I like the sound of that. 

So let's jump right in.

Sending emails with Java using an email API

There are a few things you’ll need before you get started:

1. Java installed on your machine.

2. A MailerSend account and API key. You can sign up for the free trial and start sending straight away with a testing domain. Or if you want to jump right in, subscribe to the free Hobby plan for 3,000 emails per month.

To create an API key, go to Integrations > API tokens > Manage. Click Create new token.

3. A new Java project.

Step 1: Install the MailerSend Java SDK

For this example, we’re using Maven. Add the following to the dependencies in your pom.xml file to install the MailerSend Java SDK.

<dependency>
  <groupId>com.mailersend</groupId>
  <artifactId>java-sdk</artifactId>
  <version>1.0.1</version>
</dependency>

Step 2: Set your environment variables

We always recommend using environment variables for sensitive information, especially your API keys. You can create an env file in your project and add the following:

MAILERSEND_API_KEY="your_api_key"

Or to set your variables on Linux/Mac, in your terminal enter:

export MAILERSEND_API_KEY="your_api_key"

Send an HTML email

Let’s start with a simple HTML email. You can paste the following code into your .java file and edit your from address, recipients, and content. Note that you can add multiple recipients.

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.Recipient;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;

public class MailerSendExample {

    public static void main(String[] args) {
        sendEmail(); // Call the sendEmail method
    }

    public static void sendEmail() {
        // Retrieve the API token from the environment variable
        String apiToken = System.getenv("MAILERSEND_API_KEY");

        // Check if the environment variable is set
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        // Initialize the MailerSend instance with the API token from the environment variable
        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);
        Email email = new Email();
        email.setFrom("Your Name", "Your email");
        email.addRecipient("Recipient Name", "name@example.com");

        // you can also add multiple recipients by calling addRecipient again
        email.AddRecipient("Name 2", "name2@example.com");

        // there's also a recipient object you can use
        Recipient recipient = new Recipient("Name 3", "name3@example.com");
        email.addRecipient(recipient);

        email.setSubject("This is a test");

        email.setPlain("This is the text content for a test email.");
        email.setHtml("<p>This is the <b>HTML</b> content for a test email.</p>");

        try {
            MailerSendResponse response = ms.emails().send(email);
            System.out.println("✅ Email sent! Message ID: " + response.messageId);
        } catch (MailerSendException e) {
            System.err.println("❌ Failed to send email:");
            e.printStackTrace();
        }
    }
}

To test the code, run it in your terminal with the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.MailerSendExample"

If everything worked, you should get a success message:

✅ Email sent! Message ID: 69875e81029kg1830af83572

This example sends this very simple HTML email:

Example of very simple HTML email sent via the MailerSend API with Java.

Send a templated email

The beauty of sending with an email API is that you can use professionally designed email templates instead of plain text or HTML. To send a templated email, just add the template ID to your code:

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.Recipient;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;

public class MailerSendExample {

    public static void main(String[] args) {
        sendEmail(); // Call the sendEmail method
    }

    public static void sendEmail() {

        // Retrieve the API token from the environment variable
        String apiToken = System.getenv("MAILERSEND_API_KEY");

        // Check if the environment variable is set
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        // Initialize the MailerSend instance with the API token from the environment variable
        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);

        // Create the email object
        Email email = new Email();
        email.setFrom("Your name", "Your email");
        email.addRecipient("Recipient name", "name@example.com");

        // Or use the recipient object 
        Recipient recipient = new Recipient("Name 2", "name2@example.com");
        email.AddRecipient(recipient);


        // Set the MailerSend template ID
        email.setTemplateId("3z7vklo8jng47qkge");

        email.addPersonalization("name", "John");
        email.addPersonalization("email", "john@example.com");

        try {
            // Send the email
            MailerSendResponse response = ms.emails().send(email);
            System.out.println("✅ Email sent! Message ID: " + response.messageId);
        } catch (MailerSendException e) {
            System.err.println("❌ Failed to send email:");
            e.printStackTrace();
        }
    }
}

In MailerSend, you can use the API to fetch information about your templates, including their IDs. You can also get a template’s ID from the template page in the details section on the right-hand side.

Unlike the HTML email, which you would need to build from scratch, the example above pulls in the template and uses variables to personalize the content. This is the result:

An example of an email template built in MailerSend and sent with Java using the API.

Send an email with personalization

We used a basic personalization example above, but there are a few ways you can personalize your HTML emails or templates. You can personalize for all recipients, for each recipient separately, and using POJOs:

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.Recipient;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;
import java.util.Arrays;


public class MailerSendExample {

    public static void main(String[] args) {
        sendEmail();
    }

    public static void sendEmail() {

        String apiToken = System.getenv("MAILERSEND_API_KEY");
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);

        Email email = new Email();
        email.setFrom("Your name", "Your email");

        Recipient recipient = new Recipient("Name", "name@example.com");

        email.AddRecipient(recipient);

        email.setSubject("Hey {{name}}, check out this array: {{pojo.arrayAsString}}");
        email.setPlain("Hello {{name}}, here’s your POJO data:\n- Message: {{pojo.property1}}\n- Array: {{pojo.arrayAsString}}");
        email.setHtml("<p>Hello <strong>{{name}}</strong>,</p><p>Here’s your POJO data:</p><ul><li><b>Message:</b> {{pojo.property1}}</li><li><b>Array:</b> {{pojo.arrayAsString}}</li></ul>");

        // you can add personalization for all recipients
        email.addPersonalization("var name", "Everyone");

        // you can add personalization for each recipient separately
        email.addPersonalization(recipient, "name", "John");

        // you can also add POJOs as personalization provided they can be serialized to JSON via Gson and do not have any object properties
        // Create and populate the POJO
        MyPojo obj = new MyPojo();
        obj.property1 = "This is a dynamic message!";
        obj.array1 = new int[] {
            42,
            7,
            13
        };

        // Convert the array to a string for template rendering
        obj.arrayAsString = Arrays.toString(obj.array1); // e.g. "[42, 7, 13]"

        // Add the full POJO as personalization
        email.addPersonalization("pojo", obj);

        try {
            // Send the email
            MailerSendResponse response = ms.emails().send(email);
            System.out.println("✅ Email sent! Message ID: " + response.messageId);
        } catch (MailerSendException e) {
            System.err.println("❌ Failed to send email:");
            e.printStackTrace();

        }
    }
    public static class MyPojo {
        public String property1;
        public int[] array1;
        public String arrayAsString; // This will be serialized as part of the POJO
    }
}

Notice we also added the MyPojo class here so that we could use it. Here’s what the resulting email from this example looks like:

An example of a personalized email sent with Java and the MailerSend API.

Send an email with an attachment

If you want to add an attachment to your email, you can use the attachFile method. Just make sure you’re using the correct file name and path.

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;

import java.io.File;
import java.io.IOException;

public class MailerSendExample {

    public static void main(String[] args) {
        sendEmail(); 
    }

    public static void sendEmail() {

        String apiToken = System.getenv("MAILERSEND_API_KEY");
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);

        Email email = new Email();
        email.setFrom("Your name", "Your email");
        email.addRecipient("Name", "name@example.com");

        email.setSubject("This is a test");
        email.setPlain("This is the text content for the test email with an attachment.");
        email.setHtml("<p>This is the <b>HTML</b> content for the test email with an attachment.</p>");

        // Attach a file from the filesystem
        File file = new File("invoice.pdf");
        try {
            if (file.exists()) {
                email.attachFile(file);
            } else {
                System.err.println("❌ Attachment file not found: invoice.pdf");
                return;
            }
        } catch (IOException e) {
            System.err.println("❌ Failed to attach file:");
            e.printStackTrace();
            return;
        }

        try {
            MailerSendResponse response = ms.emails().send(email);
            System.out.println("✅ Email sent! Message ID: " + response.messageId);
        } catch (MailerSendException e) {
            System.err.println("❌ Failed to send email:");
            e.printStackTrace();
        }
    }
}

Send emails in bulk

With the bulk email endpoint, you can send multiple emails (with different content) with a single API call. This lets you save your API quota and optimize your system. You could use bulk email sending for non-urgent messages such as webinar and event reminders, product launch announcements, maintenance notifications, account summaries, and more.

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.exceptions.MailerSendException;

public class MailerSendExample {

    public static void main(String[] args) {
        sendEmail();
    }

    public static void sendEmail() {

        String apiToken = System.getenv("MAILERSEND_API_KEY");
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);

        Email email1 = new Email();
        email1.setFrom("Your name", "Your email");
        email1.addRecipient("Name 1", "name1@example.com");
        email1.setSubject("This is test number 1");
        email1.setPlain("This is the text content for the first email in the test.");
        email1.setHtml("<p>This is the <b>HTML</b> content for the first email in the test.</p>");

        // Create Email 2
        Email email2 = new Email();
        email2.setFrom("Your name", "Your email");
        email2.addRecipient("Name 2", "name2@example.com");
        email2.setSubject("This is test number 2");
        email2.setPlain("This is the text content for the second email in the test.");
        email2.setHtml("<p>This is the <b>HTML</b> content for the second email in the test.</p>");


        try {
            // Send emails in bulk and get the bulk send ID
            String bulkSendId = ms.emails().bulkSend(new Email[] {
                email1,
                email2
            });

            // Print the bulk send ID
            System.out.println("✅ Emails sent! Bulk Send ID: " + bulkSendId);

        } catch (MailerSendException e) {
            System.err.println("❌ Failed to send emails:");
            e.printStackTrace();
        }
    }
}

Schedule emails

Bulk sending is particularly good for queuing different types of emails and sending them in batches to preserve your sending resources. But if you want to schedule an email—like an announcement—you can schedule them with a delay.

import com.mailersend.sdk.emails.Email;
import com.mailersend.sdk.MailerSend;
import com.mailersend.sdk.MailerSendResponse;
import com.mailersend.sdk.exceptions.MailerSendException;
import java.util.Calendar;
import java.util.Date;

public class MailerSendExample {

    public static void main(String[] args) {
        scheduleEmail(); // Call the scheduleEmail method
    }

    public static void scheduleEmail() {

        String apiToken = System.getenv("MAILERSEND_API_KEY");
        if (apiToken == null || apiToken.isEmpty()) {
            System.err.println("❌ API token not found. Please set the MAILERSEND_API_KEY environment variable.");
            return; // Exit the method if the token is missing
        }

        MailerSend ms = new MailerSend();
        ms.setToken(apiToken);

        Email email = new Email();

        email.setFrom("Your name", "Your email");
        email.addRecipient("Name", "name@example.com");

        email.setSubject("Testing Scheduling");

        email.setPlain("This is the text content for a schedule test.");
        email.setHtml("<p>This is the <b>HTML</b> content for a schedule test.</p>");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, 20);

        email.setSendAt(calendar.getTime());

        try {
            // Send the scheduled email
            MailerSendResponse response = ms.emails().send(email);
            System.out.println("Email scheduled successfully! Message ID: " + response.messageId);
        } catch (MailerSendException e) {
            e.printStackTrace();
        }
    }
}

In this example, we use calendar.add(Calendar.MINUTE, 20) to send the email in 20 minutes. You can adjust the delay using hour, date, hour_of_day, minute, year and more.

Sending emails with Java using SMTP and Jakarta Mail

For our SMTP demo, we’ll be using Jakarta Mail. To get started, you’ll need:

1. Java installed on your machine.

2. A MailerSend account and SMTP credentials. You can sign up for the free trial and start sending straight away with a testing domain. Or if you want to jump right in, subscribe to the free Hobby plan for 3,000 emails per month.

To create an SMTP user, go to Domains > Your domain > SMTP. Click Generate new user.

3. A new Java project.

Step 1: Install Jakarta Mail

We’re using Maven for our example so to install Jakarta Mail, add the following to your pom.xml file:

<dependency>
  <groupId>org.eclipse.angus</groupId>
  <artifactId>angus-mail</artifactId>
  <version>2.0.3</version>
</dependency>

You can also download Jakarta Mail from GitHub.

Step 2: Set up environment variables for your SMTP credentials

Protect your SMTP credentials by setting variables instead of hardcoding them. You can create a .env file with the following:

MAILERSEND_SMTP_USERNAME="your_username"
MAILERSEND_SMTP_PASSWORD="your_password"

Or set them in your system:

export MAILERSEND_SMTP_USERNAME="your_username"
export MAILERSEND_SMTP_PASSWORD="your_password"

Send an email

In your .java file, add the following code to send an email:

import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

import java.util.Properties;

public class MailerSendExample {
    public static void main(String[] args) throws Exception {

        // get from and to addresses
        String to = "name@example.com";
        String from = "youremail@anotherexample.com";

        // get SMTP credentials from environment variables
        final String username = System.getenv("MAILERSEND_SMTP_USERNAME");
        final String password = System.getenv("MAILERSEND_SMTP_PASSWORD");

        String host = "smtp.mailersend.net";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
            new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from, "Your name"));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("Hey, this is an SMTP test");
            message.setText("We're testing MailerSend's SMTP relay and Jakarta Mail.");

            Transport.send(message);
            System.out.println("Email Message Sent Successfully!");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

Send an email to multiple recipients

You can send a single email to multiple recipients by adding an array of email addresses:

import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

import java.util.Properties;

public class MailerSendExample {
    public static void main(String[] args) throws Exception {

        // sender email
        String from = "youremail@anotherexample.com";

        // list of recipient emails
        String[] recipients = {
            "name1@example.com",
            "name2@example.com",
            "name3@example.com"
        };

        // get SMTP credentials from environment variables
        final String username = System.getenv("MAILERSEND_SMTP_USERNAME");
        final String password = System.getenv("MAILERSEND_SMTP_PASSWORD");

        String host = "smtp.mailersend.net";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
            new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from, "Your name"));

            // create array of InternetAddress from recipient list
            InternetAddress[] recipientAddresses = new InternetAddress[recipients.length];
            for (int i = 0; i < recipients.length; i++) {
                recipientAddresses[i] = new InternetAddress(recipients[i]);
            }

            // set multiple recipients
            message.setRecipients(Message.RecipientType.TO, recipientAddresses);

            message.setSubject("Hey, this is an SMTP test");
            message.setText("We're testing MailerSend's SMTP relay and Jakarta Mail.");

            Transport.send(message);
            System.out.println("Email Message Sent Successfully!");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}
Remember:

Sending like this will send the exact same email to all recipients, meaning recipients will be able to see the other recipients that the message was sent to.

Send an email with an attachment

If you want to send an attachment, you need to use MimeBodyPart for the message body and attachment and wrap them in a Multipart object.

import jakarta.activation.DataHandler;
import jakarta.activation.FileDataSource;
import jakarta.mail.*;
import jakarta.mail.internet.*;

import java.io.File;
import java.util.Properties;

public class MailerSendExample {
    public static void main(String[] args) throws Exception {

        // email addresses
        String to = "name@example.com";
        String from = "youremail@anotherexample.com";

        // SMTP credentials from environment variables
        final String username = System.getenv("MAILERSEND_SMTP_USERNAME");
        final String password = System.getenv("MAILERSEND_SMTP_PASSWORD");

        // path to the file you want to attach
        String filePath = "path/to/your/file.pdf"; // replace with an actual path

        String host = "smtp.mailersend.net";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
            new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from, "Your name"));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("Hey, this is an SMTP test with an attachment");

            // Create the message body part
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setText("We're testing MailerSend's SMTP relay with an attachment!");

            // Create the attachment part
            MimeBodyPart attachmentPart = new MimeBodyPart();
            File file = new File(filePath);
            FileDataSource source = new FileDataSource(file);
            attachmentPart.setDataHandler(new DataHandler(source));
            attachmentPart.setFileName(file.getName());

            // Create multipart and add parts
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(textPart);
            multipart.addBodyPart(attachmentPart);

            // Set the complete message parts
            message.setContent(multipart);

            // Send the email
            Transport.send(message);
            System.out.println("Email with attachment sent successfully!");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

Send emails in bulk

You can also send emails in bulk via SMTP and Jakarta Mail using an array of emails and a for loop. In the example below, we added a pause between sendings of 1,000 milliseconds (or 1 second).

import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

import java.util.Properties;

public class MailerSendExample {
    public static void main(String[] args) throws Exception {

        // Bulk recipient list
        String[] recipients = {
            "user1@example.com",
            "user2@example.com",
            "user3@example.com"
        };

        String from = "youremail@anotherexample.com";

        final String username = System.getenv("MAILERSEND_SMTP_USERNAME");
        final String password = System.getenv("MAILERSEND_SMTP_PASSWORD");

        String host = "smtp.mailersend.net";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
            new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

        for (String to : recipients) {
            try {
                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(from, "Your name"));
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
                message.setSubject("Hey, this is an SMTP test");
                message.setText("We're testing MailerSend's SMTP relay and Jakarta Mail.");

                Transport.send(message);
                System.out.println("Email sent to: " + to);

                // Optional: pause between sends to avoid throttling
                Thread.sleep(1000);

            } catch (MessagingException e) {
                System.err.println("Failed to send to: " + to);
                e.printStackTrace();
            }
        }
    }
}

Troubleshooting and best practices for sending emails with Java

Having trouble getting your emails to work? Start with these troubleshooting tips and best practices.

1. Double check your SMTP settings: Make sure you’ve entered the correct credentials and that your environment variables are set up properly if you’re using them. You should also check your SMTP server name, port, and the email protocol command (StartTLS). You can also enable debugging to view details about the connection: session.setDebug(true);. Learn more about SMTP troubleshooting.

2. Check your SMTP port: Although port 587 is the preferred port for email sending, it can sometimes run into issues that prevent it from working. If you suspect that port 587 might be blocked, try using 2525 instead.

3. Protect sensitive information: Always use variables for data like API keys. If these fall into the wrong hands due to being hardcoded in your app, it opens up your IPs and domains to abuse.  

4. Use a reputable email service provider: Preferably one that offers technical support and developer documentation, and has a reputation for good deliverability. 

5. Handle error properly: Logging meaningful error messages can help you and others with debugging. You should also handle potential exceptions like MessagingException or IOException. 

6. Use pauses and queues: Avoid throttling by implementing pauses between sends or using a good email queuing system. 

7. Use retry logic: Prepare for potential failures by implementing retry logic. The best approach is to use an increasing delay before retries to avoid overwhelming the server.

SMTP or API: The choice is yours

Thanks to Java’s powerful libraries, using an SMTP relay service makes for a super-effective and reliable solution to deliver emails from your Java application. But if you’re looking for deeper integration of your email sending with tons more features, like tracking and templates, then an email API can’t be beat.

Test MailerSend's API and Java SDK now

Sign up for free and start sending in minutes with a trial domain. If you like what you see, subscribe to a free Hobby plan for 3,000 emails per month.

Amy Elliott
I’m Amy, Content Writer at MailerSend. As a child, I dreamt about writing a book and practiced by tearing pages from an A4 notepad and binding them with sugar paper. The book is pending but in the meantime, I love taking a deep dive into technical topics and sharing insights on email metrics and deliverability.