The Jakarta Mail API offers a robust framework for creating email messaging applications using the popular Java programming language. With the API, you can send and receive emails via Simple Mail Transfer Protocol (SMTP), Internet Message Access Protocol (IMAP), or Post Office Protocol (POP).
What is Jakarta Mail?
For a long time, the Java Enterprise Edition (commonly known as Java EE), has been the de facto platform for developing mission-critical applications.
Recently, in order to stir the creation of cloud-native applications, several prominent software vendors joined hands to transfer Java EE technologies to the Eclipse Foundation, which is a not-for-profit organization tasked with stewarding the activities of the Eclipse open source software community.
Consequently, the Java EE has been rebranded to Jakarta EE. Notably, as of July 2018, the mail package that was known as JavaMail API, has been further enhanced by the Eclipse Foundation and renamed to Jakarta Mail.
In spite of the name change, all the main classes and properties definitions still remain the same for both Jakarta Mail and JavaMail.
In this article, we’re going to illustrate how to utilize the Jakarta Mail project to send different types of email messages.
Getting started with Jakarta Mail
To get started using Jakarta Mail, you can download the jakarta.mail.jar file available on the Jakarta Mail project website. Then, you should set your CLASSPATH environment variable to consist of the downloaded “jakarta.mail.jar” file and the current directory.
For example, in a Windows machine, if you have downloaded the file to the /you/you/download/ directory, the following would work:
set CLASSPATH=%CLASSPATH%;c:\download\jakarta.mail.jar;.
Besides, since the Jakarta Mail jar files are available on the Maven repository, you can specify the following Maven dependency and add them to your work environment.
<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
Jakarta Mail API Core Classes
The Jakarta Mail API has a wide range of classes and interfaces that can be used for sending, reading, and performing other actions with email messages—just like in a typical mailing system.
Although there are several packages in the Jakarta Mail Project, two of the most frequently used ones are javax.mail and javax.mail.internet.
The javax.mail package provides classes that model a mail system and the javax.mail.internet package provides classes that that are focused to Internet mail systems.
Here is a description of the core classes in each of the packages:
1. javax.mail.Session
The Session class, which is not subclassed, is the top-level class of the Jakarta Mail API. It’s a multi-threaded object that acts as the connection factory for the Jakarta Mail API—apart from collecting the mail API’s properties and defaults, it is responsible for configuration settings and authentication.
To get the Session object, you can call either of the following two methods:
- getDefaultInstance(), which returns the default session
- getInstance(), which returns a new session
2. javax.mail.Message
The Message class is an abstract class that models an email message; its subclasses support the actual implementations. Usually, its MimeMessage subclass (javax.mail.internet.MimeMessage) is used for actually crafting the details of the email message to be sent. A MimeMessage is an email message that uses the MIME (Multipurpose Internet Mail Extension) formatting style.
Here are some of the commonly used methods of the MimeMessage class:
- setFrom(Address addresses)—it’s used to set the “From” header field.
- setRecipients(Message.RecipientType type, String addresses)—it’s used to set the stated recipient type to the provided addresses. The possible defined address types are “TO” (Message.RecipientType.TO), “CC” (Message.RecipientType.CC), and “BCC” (Message.RecipientType.BCC).
- setSubject(String subject)—it’s used to set the email’s subject header field.
- setText(String text)—it’s used to set the provided String as the email’s content, using MIME type of “text/plain”.
- setContent(Object message, String contentType)—it’s used to set the email’s content, using MIME type of “text/html”.
3. javax.mail.Address
The Address class is an abstract class that models the addresses (To and From addresses) in an email message; its subclasses support the actual implementations. Usually, its javax.mail.internet.InternetAddress subclass, which denotes an Internet email address, is commonly used.
4. javax.mail.Authenticator
The Authenticator class is an abstract class that is used to get authentication to access the mail server resources—often by requiring the user’s information. Usually, its PasswordAuthentication subclass is commonly used.
5. javax.mail.Transport
The Transport class is an abstract class that uses the SMTP protocol for submitting and transporting email messages.
How to send an email in Jakarta Mail
After illustrating the main classes in the Jakarta Mail Project, let’s now see how to implement them to send a simple email message via an SMTP server.
Essentially, here are the steps for sending an email message using the Jakarta Mail API:
- Configure the SMTP server details using the Java Properties object. For this demonstration, we’ll use Mailtrap to set up our SMTP server. Mailtrap is a simple tool that provides a fake SMTP server for testing, reviewing, and analyzing email functionalities during development. You can visit the Mailtrap’s website to open an account and get your free SMTP server details. Or, you can also get SMTP server details from any other email service provider.
- Create a Session object by calling the getInstance() method. Then, pass the Mailtrap’s username and password to PasswordAuthentication. When creating the session object, you should always register the Authenticator with the Session.
- Once the Session object is created, the next step is to create the email message to be sent. To do this, start by passing the created session object in the MimeMessage class constructor.
- Next, after creating the message object, set the From, To, and Subject fields for the email message.
- Use the setText() method to set the content of the email message.
- Use the Transport object to send the email message.
- Add Exceptions to retrieve the details of any possible errors when sending the message.
Here is the code for using the Jakarta Mail API for sending email messages:
package jakartaemail;
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 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 javax.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 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 we compile and run the above code, and open our Mailtrap inbox, here’s the output we get:
It worked!
Sending HTML email in Jakarta Mail
While the process of sending an HTML email using the Jakarta Mail Project is mostly the same as sending a simple email message, the only difference is that here, instead of the setText() method, we’ll be using the setContent() method to set content and specify “text/html” in the second argument, indicating the message has HTML content.
Here is the code:
package jakartaemail;
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 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 javax.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 Jakarta Mail!");
//set the content of the email message
message.setContent("Just discovered that Jakarta Mail is fun and easy to use", "text/html");
//send the email message
Transport.send(message);
System.out.println("Email Message Sent Successfully");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Here is the output:
Send an Email with Attachments in Jakarta Mail
Apart from the previously mentioned steps, here are the differing steps involved in using the Jakarta Mail API for sending email attachments:
- Create an instance of the MimeMultipart object that will be used for wrapping the MimeBodyPart body parts. A Multipart acts like a container that keeps multiple body parts, and it comes with methods for getting and setting its various subparts.
- Then, set the first part of the multipart object by passing the actual message to it.
- Next, set the second part of the multipart object by adding the attachment using a DataHandler object.
- Include the multipart in the message to be sent.
Here is the code:
package jakartaemail;
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;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.activation.DataSource;
import javax.activation.DataHandler;
import javax.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 javax.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);
}
}
}
Here is the output:
Debug Jakarta Mail
Debugging plays a critical role in testing of email sending. In Jakarta Mail, it’s pretty straightforward. Set debug to true in the properties of your email code:
props.put("mail.debug", "true");
As a result, you will get a step by step description of how your code is executed. If any problem with sending your message appears, you will instantly understand what happened and at which stage.
Here is how our HTML message debug output looks:
DEBUG: Jakarta Mail version 1.6.4
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.mailtrap.io, user=diana, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.mailtrap.io", port 2525, isSSL false
220 mailtrap.io ESMTP ready
DEBUG SMTP: connected to host "smtp.mailtrap.io", port: 2525
EHLO DESKTOP-NLP1GG8
250-mailtrap.io
250-SIZE 5242880
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-AUTH PLAIN LOGIN CRAM-MD5
250 STARTTLS
DEBUG SMTP: Found extension "SIZE", arg "5242880"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN CRAM-MD5"
DEBUG SMTP: Found extension "STARTTLS", arg ""
STARTTLS
220 2.0.0 Start TLS
EHLO DESKTOP-NLP1GG8
250-mailtrap.io
250-SIZE 5242880
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 AUTH PLAIN LOGIN CRAM-MD5
DEBUG SMTP: Found extension "SIZE", arg "5242880"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN CRAM-MD5"
DEBUG SMTP: protocolConnect login, host=smtp.mailtrap.io, user=1e2b3c4d5e6f7g, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<yourmail@example.com>
250 2.1.0 Ok
RCPT TO:<johndoe@gmail.com>
250 2.1.0 Ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP: johndoe@gmail.com
DATA
354 Go ahead
Date: Tue, 30 Jul 2019 17:19:31 +0200 (EET)
From: yourmail@example.com
To: johndoe@gmail.com
Message-ID: <20132171.0.1548256771226@DESKTOP-NLP1GG8>
Subject: My HTML message
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<div><span style="color:#57aaca;">c</span><span style="color:#57aec5;">o</span><span style="color:#57b2c0;">l</span><span style="color:#57b6ba;">o</span><span style="color:#57bbb5;">r</span><span style="color:#56bfb0;">f</span><span style="color:#56c3ab;">u</span><span style="color:#56c7a5;">l</span><span style="color:#56cba0;"> </span><span style="color:#5ec3ab;">m</span><span style="color:#65bbb6;">e</span><span style="color:#6db3c1;">s</span><span style="color:#75accd;">s</span><span style="color:#7da4d8;">a</span><span style="color:#849ce3;">g</span><span style="color:#8c94ee;">e</span></div>
.
250 2.0.0 Ok: queued
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 2.0.0 Bye
Sent message successfully....
Wrapping up
That’s how you can use the Jakarta Mail API to send email messages in Java. We hope that this article will help you to get started with the API and add powerful emailing capabilities to your Java applications.
Of course, we’ve just scratched the surface about what is possible with the Jakarta Mail Project. If you want to explore more usage samples, you can always check its expansive documentation.
Importantly, when using Jakarta Mail, don’t forget to always test your emails in your development environment before broadcasting them to users.
Enjoy using Jakarta Mail!