Stand with Ukraine 🇺🇦 Donate to support

How to Send Emails in Java: 2022 Guide

On October 18, 2022
14min read
Diana Lepilkina Content Specialist @Mailtrap

Java has consistently been ranked as one of the most popular web programming languages for many years, and its popularity is still going strong in late 2022.

This popularity aspect is something Java has in common with emails which have been a must-have communication tool for all companies that do their best to keep users up-to-date and provide them with necessary information regarding their accounts, passwords, verification, and more.

Considering the fact that you are reading this article, you are most likely aware that you can use Java to send email messages to your users. And in this tutorial, we will demonstrate exactly how to do so, as well as how to complete a couple of other additional yet often-necessary steps.

Excited? Let’s dive in!

What is the most popular option for sending emails using Java?

When scouring the internet for tutorials on sending emails using Java, there is a high chance every single one will mention something called “Jakarta Mail” or “JavaMail”.

To avoid confusion, it’s important to note right off the bat that JavaMail is only the former name of Jakarta Mail and the two represent the same software.

So, Jakarta Mail, or JavaMail as some still like to call it, is an API for sending and receiving emails via SMTP, POP3, as well as IMAP and is the most popular option that also supports both TLS and SSL authentication. It is platform-independent, protocol-independent, and built into the Jakarta EE platform. You can also find Jakarta Mail as an optional package for use with the Java SE platform.

How to send emails in Java using Jakarta Mail and SMTP?

Step 1 – Learn Jakarta Mail (JavaMail) basics

Installation

To start working with Jakarta Mail, first, you should add the jakarta.mail.jar file into your CLASSPATH environment. You can download the file from the Jakarta Mail project page on GitHub

You can also find the jakarta.mail.jar file in the Maven repository and add it to your environment with Maven dependencies:

       <dependencies>
        <dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>2.0.1</version>
</dependency>
        </dependencies>

At the moment of writing this article, the latest Jakarta Mail release is 2.0.1. 

Note: Within the code in some tutorials, you might see javax.mail instead of jakarta.mail. This shouldn’t worry you, as it’s just the API reference used in dependencies representing the older version of Jakarta Mail.

Classes and methods

Before we move to the code, let’s go over some Jakarta Mail basics you should be familiar with to build and send messages.

The first and probably most significant thing we will mention is the Message class. The Message class is abstract, meaning that in order to create a message object, you need to use one of its subclasses capable of implementing the message. 

For internet email messages that conform to the RFC822 and MIME standards, that subclass is MimeMessage.

Once created, the MIME-style email message is filled in with attributes and content. 

The MimeMessage subclass has a range of methods you can use to change message details, such as the message “From” header field, “Subject” header field, content, recipient addresses for a specific recipient type, and more. 

To learn more about Jakarta Mail classes and their most popular methods, as well as get a detailed guide on using Jakarta Mail, refer to our Jakarta Mail tutorial

Step 2 – Create and send a simple Jakarta Mail message via an SMTP server

With the basics out of the way, it’s time to get to the actual email-sending process. 

The code example below will be all you need to send an email using the Jakarta Mail API, so feel free to copy-paste it into your project and then run it. 

Do keep in mind that the SMTP server details should be adjusted according to the SMTP server of the email service provider you are using. So, for instance, if you want to send emails in Java using the Gmail SMTP server, the host address will be “smtp.gmail.com”.

package org.example.jakartaemail;
import java.util.Properties;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

public class JakartaEmail {
   public static void main(String[] args) {
      //provide recipient's email ID
      String to = "jakartato@example.com";
      //provide sender's email ID
      String from = "jakartafrom@example.com";
      //provide Mailtrap's username
      final String username = "a094ccae2cfdb3";
      //provide Mailtrap's password
      final String password = "82a851fcf4aa33";
      //provide Mailtrap's host address
      String host = "smtp.mailtrap.io";
      //configure Mailtrap's SMTP server details
      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");
      //create the Session object
      Session session = Session.getInstance(props,
         new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
    }
         });
      try {
    //create a MimeMessage object
    Message message = new MimeMessage(session);
    //set From email field
    message.setFrom(new InternetAddress(from));
    //set To email field
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
    //set email subject field
    message.setSubject("Here comes Jakarta Mail!");
    //set the content of the email message
    message.setText("Just discovered that Jakarta Mail is fun and easy to use");
    //send the email message
    Transport.send(message);
    System.out.println("Email Message Sent Successfully");
      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

If you want to make your message an HTML email instead of plain text, you only need to replace the setText(String text) method with the setContent(Object o, String type) one and put “text/html” as the second method argument.

But, if you want your message to contain both HTML and plain text, you need to build it using a MimeMultipart(“alternative”) object.

For this, you should create two different parts manually and insert them separately – text/plain body as the first part of the multipart and the text/html body as the second part.

Pretty straightforward, right?

How to send emails in Java using Mailtrap Email API?

Mailtrap Email API is an end-to-end sending solution with a sending throughput of up to ~10,000 emails/second. 

If we were to pick a standout feature of Email API, that would without a doubt be its actionable analytics consisting of deliverability alerts, 60-day email logs, and dashboards with critical metrics which enable its users to spot and fix sending issues and thus have more control over their email deliverability.

The Email API also comes with dedicated IPs, suppression lists, IP auto warm-up, and more. So, if you’re looking for a tool that will not only send your emails but also help you get those emails to the right inboxes, then Mailtrap Email API is definitely worth a try!

What does sending emails with Mailtrap Email API look like?

First, sign up for a Mailtrap account.

Then, you navigate to the Sending Domains section of your Mailtrap dashboard to add your domain and verify it. Then pick between sending with API or SMTP. 

If you go for API, pick Java from the dropdown menu, and copy the code provided.

Paste the copied code into your Java app and run it.

OkHttpClient client = new OkHttpClient().newBuilder()
    .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"from\":{\"email\":\"mailtrap@mailtrap.club\",\"name\":\"Mailtrap Test\"},\"to\":[{\"email\":\"you@example.com\"}],\"subject\":\"You are awesome!\",\"text\":\"Congrats for sending test email with Mailtrap!\",\"category\":\"Integration Test\"}");
Request request = new Request.Builder()
    .url("https://send.api.mailtrap.io/api/send")
    .method("POST", body)
    .addHeader("Authorization", "Bearer <your api token>")
    .addHeader("Content-Type", "application/json")
    .build();
Response response = client.newCall(request).execute();

For sending with SMTP, on the other hand, just copy-paste the provided settings to your email sending service or app. This will allow you to use Mailtrap as an SMTP server.

And you are done! Email sending with Mailtrap is now enabled!

How to send HTML emails with images?

So, earlier we covered how to turn your plain text email into an HTML email. But what if you want to customize that email even further and add some images to it? We have got you covered on that end as well!

To add an image to your HTML email in Jakarta Mail, you can choose any of the three common options: CID image embedding, inline embedding or Base64 encoding, and linked images. To do CID image embedding, you need to create a MIME multipart/related message using the following code:

Multipart multipart = new MimeMultipart("related");
        MimeBodyPart htmlPart = new MimeBodyPart();
        //add reference to your image to the HTML body <img src="cid:some-image-cid" alt="img" />
        htmlPart.setText(messageBody, "utf-8", "html");
        multipart.addBodyPart(htmlPart);
        MimeBodyPart imgPart = new MimeBodyPart();
        // imageFile is the file containing the image
        imgPart.attachFile(imageFile);
        // or, if the image is in a byte array in memory, use
        // imgPart.setDataHandler(new DataHandler(
        //      new ByteArrayDataSource(bytes, "image/whatever")));
        imgPart.setContentID("<some-image-cid">");
        multipart.addBodyPart(imgPart);
        message.setContent(multipart);

For inline embedding or Base64 encoding, you should include the encoded image data in the HTML body similar to this:

<img src="data:image/jpeg;base64,base64-encoded-data-here" />

Note: Each Base64 digit represents 6 bits of data, so your actual image code will be pretty long. As this affects the overall size of the HTML message, it’s better not to inline large images.

Lastly, we have linked images that are essentially images hosted on some external server that you then create a link to. You can do that using the img tag in the HTML body like so:

<img src="/wp-content/uploads/2018/11/blog/-illustration-email-embedding-images.png" alt="img" />

Full code example:

package com.example.smtp;
import java.util.Properties;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

public class SendHTMLEmail {
   public static void main(String[ ] args) {
      String to = "johndoe@gmail.com";
      String from = "yourmail@example.com";
      final String username = "1a2b3c4d5e6f7g";//generated by Mailtrap
      final String password = "1a2b3c4d5e6f7g";//generated by Mailtrap
      String host = "smtp.mailtrap.io";
      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", "2525");
      // Get the Session object.
      Session session = Session.getInstance(props,
         new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
            }
	});
      try {
            // Create a default MimeMessage object.
            Message message = new MimeMessage(session);
   	message.setFrom(new InternetAddress(from));
	message.setRecipients(Message.RecipientType.TO,
              InternetAddress.parse(to));
	message.setSubject("My HTML message");
	   // Put your HTML content using HTML markup
	   message.setContent(
              "<p> The text and the <strong>image</strong>
<img src="/wp-content/uploads/2018/11/blog/-illustration-email-embedding-images.png" alt="img" /> "
,
             "text/html");
	   // Send message
	   Transport.send(message);
	   System.out.println("Sent message successfully....");
      } catch (MessagingException e) {
	   e.printStackTrace();
	   throw new RuntimeException(e);
      }
   }
}

How to send emails with attachments?

Adding attachments to your emails is often a necessity, and in Jakarta Mail, it is achieved using the already-mentioned MimeMultipart object. The first part of the object is the main one (the text), while the second part is the attachment, be it a .txt, .png, or some other type of attachment.

When put into code, this is what it should look like:

package jakartaemail;
import java.util.Properties;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.BodyPart;
import jakarta.mail.Multipart;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;
import jakarta.activation.DataSource;
import jakarta.activation.DataHandler;
import jakarta.activation.FileDataSource;

public class JakartaEmail {
   public static void main(String[] args) {
      //provide recipient's email ID
      String to = "jakartato@example.com";
      //provide sender's email ID
      String from = "jakartafrom@example.com";
      //provide Mailtrap's username
      final String username = "a094ccae2cfdb3";
      //provide Mailtrap's password
      final String password = "82a851fcf4aa33";
      //provide Mailtrap's host address
      String host = "smtp.mailtrap.io";
      //configure Mailtrap's SMTP server details
      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");
      //create the Session object
      Session session = Session.getInstance(props,
         new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
    }
         });
      try {
    //create a MimeMessage object
    Message message = new MimeMessage(session);
    //set From email field
    message.setFrom(new InternetAddress(from));
    //set To email field
    message.setRecipients(Message.RecipientType.TO,
               InternetAddress.parse(to));
    //set email subject field
    message.setSubject("Here comes an attachment!");
   //create the message body part
    BodyPart messageBodyPart = new MimeBodyPart();
    //set the actual message
    messageBodyPart.setText("Please find the attachment sent using Jakarta Mail");
    //create an instance of multipart object
    Multipart multipart = new MimeMultipart();
    //set the first text message part
    multipart.addBodyPart(messageBodyPart);
    //set the second part, which is the attachment
    messageBodyPart = new MimeBodyPart();
    String filename = "C:\\Users\\OPIDI\\Desktop\\File 1\\gantt2.png";
    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);
    //send the entire message parts
    message.setContent(multipart);
    //send the email message
    Transport.send(message);
    System.out.println("Email Message Sent Successfully");
      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

If you are using a newer version of Jakarta Mail, you can replace the following piece of code with methods:

messageBodyPart = new MimeBodyPart();
    String filename = "C:\\Users\\OPIDI\\Desktop\\File 1\\gantt2.png";
    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);
    multipart.addBodyPart(messageBodyPart);

The methods are available to users of Jakarta Mail 1.4 and above, and make attaching a file a much simpler process:

void attachFile(File file)
void attachFile(String filePath)

What the methods look like when integrated into our code example:

messageBodyPart = new MimeBodyPart();
    String filename = "C:\\Users\\OPIDI\\Desktop\\File 1\\gantt2.png";
messageBodyPart.attachFile(filename);
    multipart.addBodyPart(messageBodyPart);

As both versions of the code work in Jakarta Mail 1.4 or above, feel free to use whichever one you prefer to create emails with attachments. 

How to send emails to multiple recipients?

To implement multiple recipients in Jakarta Mail, you need to use the setRecipients method we already showcased in our code, only this time, instead of passing just one email address, you need to pass an array of them like so:

Address[] toAddresses = new InternetAddress[] {
new InternetAddress("abc@abc.example"),
new InternetAddress("abc@def.example"),
new InternetAddress("ghi@abc.example")};
message.setRecipients(Message.RecipientType.TO, toAddresses);

The method addRecipients functions in the same way as setRecipients, so you can use that as an alternative. We went with setRecipients to stay consistent with the code snippets provided thus far in the article.

How to test emails in Java?

When it comes to emails, on your list of priorities, right after enabling email sending should be enabling email testing since, without it, the emails you thought were well-crafted might never reach recipients’ inboxes.

Our choice in terms of email testing tools falls on Mailtrap Email Sandbox part of the Mailtrap Email Delivery Platform, along with the Email API we talked about earlier. 

Email Sandbox is an environment for previewing, inspecting, and debugging emails safely in staging before they are sent out to recipients. It has the ability to analyze each email for spam in content as well as validate its HTML/CSS regardless of whether it was custom-made or based on an HTML template. Also, it enables you to send as many test emails as you want in order to perfect things, all while not risking accidentally sending them to real recipients.

The tool takes about 5 minutes to set up, thus saving you the time and hassle otherwise necessary to configure your own SMPT mail server. On top of that, it helps in preserving your domain reputation as you won’t have the need to do manual testing using your own personal inbox.

So, how do you get started with Email Sandbox? It’s pretty easy!

Go into the Inboxes section of the Mailtrap platform and navigate to SMTP settings. 

After that, copy-paste the code below into your project, change details such as the username, password, and anything else necessary, and run it.

package com.example.smtp;
import java.util.Properties;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

public class SendEmail {
   public static void main(String[] args) {
      // Put recipient's address
      String to = "test@example.com";
      // Put sender's address
      String from = "from@example.com";
      final String username = "1a2b3c4d5e6f7g";//username generated by Mailtrap
      final String password = "1a2b3c4d5e6f7g";//password generated by Mailtrap
      // Paste host address from the SMTP settings tab in your Mailtrap Inbox
      String host = "smtp.mailtrap.io";
      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");//it’s optional in Mailtrap
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "2525");// use one of the options in the SMTP settings tab in your Mailtrap Inbox
      // Get the Session object.
      Session session = Session.getInstance(props,
         new jakarta.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
               return new PasswordAuthentication(username, password);
    }
         });
      try {
    // Create a default MimeMessage object.
    Message message = new MimeMessage(session);
    // Set From: header field
    message.setFrom(new InternetAddress(from));
    // Set To: header field
    message.setRecipients(Message.RecipientType.TO,
               InternetAddress.parse(to));
    // Set Subject: header field
    message.setSubject("My first message with JavaMail");
    // Put the content of your message
    message.setText("Hi there, this is my first message sent with JavaMail");
    // Send message
    Transport.send(message);
    System.out.println("Sent message successfully....");
      } catch (MessagingException e) {
         throw new RuntimeException(e);
      }
   }
}

Lastly, go into the Inboxes section of the Email Sandbox, where you should see the test email sent using the code, and start with the previewing, inspecting, and/or debugging.

Need more options for sending emails in Java?

Over the course of this article, we’ve guided you through the main Jakarta Mail use cases and options. Should you experience any difficulties in installing, implementing, or using this API, refer to the Jakarta Mail FAQ.

That being said, we do understand that creating transactional emails and sending them from your Java application with the Jakarta Mail API does take time. So, as an alternative, feel free to consider these other more simplified options.

Spring Framework

Spring is a utility library built on top of the JavaMail API encapsulating its specifics.

The main email package in Spring is org.springframework.mail, while MIME features can be used with the help of org.springframework.mail.javamail.MimeMessagePreparator.

To start using Spring, you first need to add the dependency using Maven or Gradle. 

You can get the code for adding the latest version of the dependency on its Maven Repository page or simply use the code we provided in this article.

The following should be placed in your pom.xml file:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.3.23</version>
</dependency>

After that is complete, copy-paste the following code into your project. It will take care of everything, starting from obtaining an implementation of the MailSender interface, connecting to an SMTP server, creating a message, and sending the message as the final step:

@Bean
public JavaMailSender getJavaMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    mailSender.setHost("smtp.mailtrap.io");
    mailSender.setPort(2525);
    mailSender.setUsername("1a2b3v4d5e6f7g");
    mailSender.setPassword("1a2b3v4d5e6f7g");
    Properties props = mailSender.getJavaMailProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.debug", "true");
    return mailSender;
}
Simple email
@Component
public class EmailServiceImpl implements EmailService {
    @Autowired
    public JavaMailSender emailSender;
    public void sendSimpleMessage(
      String to, String subject, String text) {
        ...
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(to);
        message.setSubject(subject);
        message.setText(text);
        emailSender.send(message);
        ...
    }
}:

Apache Commons Email

Apache Commons Email is also built on top of the JavaMail API with the aim of simplifying it. And despite it not being as complex, it still supports classes for building and sending HTML emails, emails with attachments, or even emails with embedded images.

Apache Commons Email can be used as a base for other email wrappers as well. For example, mailR, for sending emails using R or Play Framework.

For our demonstration of Apache Commons Email, we are not going deep into details. Instead, we will just show the steps for creating a basic HTML email.

As is common practice, we start with adding the dependency:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-email</artifactId>
  <version>1.5</version>
</dependency>

After that, we proceed with code that will complete the rest of the steps upon running it:

App.java
package app;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;

public class App {
  public static void main(String[] args) throws EmailException {
    HtmlEmail mail = new HtmlEmail();
    mail.setHostName("smtp.mailtrap.io");
    mail.setSmtpPort(2525);
    mail.setAuthenticator(new DefaultAuthenticator("1a2b3c4d5e6f7g", "1a2b3c4d5e6f7g"));
    mail.setFrom("from@example.com", "From");
    mail.addTo("to@example.com", "To");
    mail.setSubject("Apache Commons email test");
    mail.setHtmlMsg("<p style='font-size:16px;color:green'>Here is your example</p>");
    mail.send();
 }
}

Simple Java Mail

Last but not least, we have maybe the simplest mailing library ever – Simple Java Mail. This library is a wrapper around the JavaMail API and removes the need to use numerous Java email classes and properties. And just as is the case with Apache Commons Email, Simple Java Mail’s simplicity doesn’t prevent it from supporting HTML, images, and attachments, as well as templates. 

It’s also secure and reliable, as it facilitates signing emails with DKIM, uses S/MIME encryption, gets regularly updated, and has a comprehensive set of code samples.

To make use of Simple Java Mail for email sending in Java, first add the dependency:

<dependency>
    <groupId>org.simplejavamail</groupId>
    <artifactId>simple-java-mail</artifactId>
    <version>7.5.0</version>
</dependency>

After that, use your version of the short code snippet below to create your email and send it off:

Email email = EmailBuilder.startingBlank()
    .from("From", "from@example.com")
    .to("To", "to@example.com")
    .to("You too", "you@example.com")
    .withSubject("Simple Java Mail testing!")
    .withPlainText("Looks like it’s really simple!")
    .buildEmail();
MailerBuilder
 .withSMTPServer("smtp.mailtrap.io", 2525, "1a2b3c4d5e6f7g", "1a2b3c4d5e6f7g")
  .withTransportStrategy(TransportStrategy.SMTPS);
  .buildMailer()
  .sendMail(email);

Final words

Adding the email-sending functionality to your Java application is not the easiest task. While trying to complete it, you will need to learn and experiment, try and fail. Luckily, there are some easier options like Simple Java Mail for those wanting to avoid the hassle that comes with using the most popular one, Jakarta Mail.

All in all, we hope that after reading this article on how to send emails using Java, you at least have an idea of where to start in creating beautiful emails, either from scratch or using an HTML email template and sending them from your application. Just remember to make use of software solutions like the Mailtrap Email Delivery Platform to efficiently test, send and control your emails.

Article by Diana Lepilkina Content Specialist @Mailtrap

Comments

1 replies

Tony Mohapatra

Sending an dynamic url in email body through java mail api is trying to access Or ping Or open the url which indirectly making a get request to my servlet. How to prevent it. Kindly sugget me

Comments are closed.