Guide to Send Emails in Java

Java has been ranking as one of the most popular web programming languages for many years. In this tutorial, we will demonstrate how to send HTML emails in Java using its native functionality, and also review several popular libraries.

The main option is to use a Java API for sending and receiving emails via SMTP, POP3, and IMAP. It is implemented as an optional package compatible with any operating system. At the same time, Jakarta Mail is supplied as a part of Jakarta EE and Java EE platforms. In the earlier releases, the mail package was titled “JavaMail API”. However, since July 2019, the Java software has been further developed by the Eclipse Foundation. This is why the email package also got the new name. All main classes and properties are the same for both JavaMail and Jakarta Mail. 

Jakarta Mail (JavaMail) basics

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

Besides, you can find Jakarta Mail jar files in the Maven repository and add them to your environment with Maven dependencies:

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

To build messages with Jakarta Mail, you will need to learn its classes and properties first. 

Before we move to code, let’s review core classes and properties, which are most frequently used for building and sending messages with Jakarta Mail.

For example, Message class (javax.mail.Message) is an abstract class for actually building an email message. Its Mime Message (javax.mail.internet.MimeMessage) subclass and its main methods are commonly used:

  • setFrom(Address[ ] addresses) sets the “From” header field
    public void addFrom(Address[ ] addresses)
  • addRecipients(Message.RecipientType type, String addresses) adds the given address to the recipient type
    public void addRecipient(Message.RecipientType type, Address[ ] addresses)
    Message.RecipientType.TO “To”
    Message.RecipientType.CC “Cc”
    Message.RecipientType.BCC “Bcc”
    MimeMessage.RecipientType.NEWSGROUPS “Newsgroups”

To learn more about classes and properties, as well as get a detailed guide on using Jakarta Mail, refer to our Jakarta Mail Tutorial

Here, we will quickly review sending emails via SMTP and adding an HTML part. 

Simple Jakarta Mail message via an SMTP server

First of all, we need to define who sends what to who. So, use the SendEmail public class and set “from” and “to” email addresses and add the subject. With javax.mail.PasswordAuthentication class we will be able to require password authentication to send a message via SMTP server.

In the properties method, we will add the necessary SMTP settings and then create a mail Session object. Afterward, you can create a Message using the MimeMessage.

Finally, send your message with the Transport object.

Don’t forget to add Exceptions. This class enables you to get details on possible errors along with an understanding of how to debug them. The main one is MessagingException. It can be used within javax.mail, javax.mail.internet, and javax.mail.search packages. For example, AddressException for javax.mail.internet will be thrown if you offered a wrongly formatted address.

How to test emails in Java?

For testing email sending from Java, we will use Mailtrap, an online tool, which helps test, review, and analyze emails sent from dev, QA, or staging environments, without the risk of spamming your customers or colleagues. Once you have tested and verified that everything works properly, change settings for the server you use in production.

Input:

package com.example.smtp;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.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 javax.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);
      }
   }
}

Output:

Start Testing

Sending HTML email with images

To send an HTML email, you should perform the same steps as for sending a simple text message, with only SendHTMLEmail class instead of just SendEmail. Also, you need to set content to the MimeMessage.setContent(Object, String) and indicate text/html type.

To add an image to your HTML email in Jakarta Mail, you can choose any of three regular variants: CID, base64 image, or linked image.

To embed a CID image, you need to create a MIME multipart/related message:

  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 a base64, or inlined image, include the encoded image data in the HTML body:

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

But remember that each Base64 digit represents 6 bits of data, so your actual image code will be pretty long. Besides, it affects the overall size of the HTML message, so it’s better not to inline large images.

The simplest way to add an image is just linking to the image hosted on some external server. Refer to your image as a link in the HTML body with animgtag:

<img src="https://blog.mailtrap.io/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 javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.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 javax.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="https://blog.mailtrap.io/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);
      }
   }
}

In Mailtrap, you can also check the raw data of your message as well as its HTML source on separate tabs. If you would like your message to contain both HTML and plain text, you need to build it using a MimeMultipart(“alternative”) object. You should create two different parts manually and insert them separately: text/plain body part as the first part in the multipart the text/html body part as the second one.

Inspect&Debug Your Emails

Need More Options?

We have guided you through the main Jakarta Mail use cases and options. Should you experience any difficulties in installing, implementing, or using this package, refer to the Jakarta Mail FAQ.

Constructing transactional emails to send from your Java app with the Jakarta Mail API does takes time. Alternatively, you can consider options for simplified email sending in Java. 

Spring Framework

Spring email infrastructure is built on top of the JavaMail API. It has a quite similar structure and logic. 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. 

Let’s review a simple example.
Start with dependencies:

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

Set up an SMTP server:

@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 JavaMail API. It looks much simpler and supports all the features you need to build and design your email messages (HTML, images, attachments, and templates). We are not going to go deep into detail here, we’re just giving an idea of how a basic email should look.

Maven Dependency

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

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();
 }
}

As you can see, it does simplify email sending. Apache Commons is also used as a base for other email wrappers. For example, mailR, for sending emails from R, or Play Framework. 

Simple Java Mail

Simple Java Mail is one of the simplest libraries ever – in fact, it is a wrapper around the JavaMail (Jakarta Mail) API.

Simple Java Mail mitigates the use of numerous Java email classes and properties. At the same time, it is full-featured, with a support for HTML, images, and attachments, as well as templates. It is secure and reliable, as it allows for the signing of emails with DKIM and uses S/MIME encryption. The library is regularly updated and has a comprehensive set of code samples. 

Compare the following code with other Java-related examples:

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

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 email sending functionality to your Java app is not the easiest task. You will need to learn and experiment, try and fail. Luckily, there are some easier alternatives like Simple Java Mail. We are sure that after reading this post you have an idea for where to start to create beautiful emails that really work, and send them from your Java app. Just don’t forget to work in a development environment while experimenting and thoroughly test everything before you move to production! 

Add comment

E-mail is already registered on the site. Please use the Login form or enter another.

You entered an incorrect username or password

Sorry, you must be logged in to post a comment.

1 comment

by Newest
by Best by Newest by Oldest

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