Simple examples for sending emails from JavaMail API

Published on 2019-10-06· Updated on 2024-01-25

The author voluntarily contributed this tutorial as a part of Pepipost Write to Contribute program.

Introduction

JavaMail API provides a platform and protocol-independent framework to build mail and messaging client applications using Java.

The JavaMail API is a versatile framework that offers abstract classes representing objects defined within the email system, serving as interfaces for email applications. As a tool for reading and sending emails, it requires service providers to facilitate interactions with mail servers that operate using transport protocols such as:

  1. Simple Mail Transfer Protocol(SMTP)
    SMTP is an internet standard for sending and receiving emails across IP networks, employing TCP on port 25 for this purpose. To enhance security, SSL can be used to secure connections. The JavaMail API includes packages and core classes, such as com.sun.mail.smtp, which functions as an SMTP protocol provider, enabling connections to various SMTP servers.
  2. Internet Message Access Protocol(IMAP)
    An IMAP server typically listens on port 143, and for secure connections using IMAP over SSL, the assigned port is 993. You can utilize the IMAP protocol provider in the JavaMail API, found in the package com.sun.mail.imap, to interact with IMAP servers.
  3. Post Office Protocol (POP)
    POP3 is an internet standard protocol employed by local email clients to retrieve email from a remote server over TCP/IP. POP3 servers typically listen on port 110. You can utilize the POP3 protocol provider in the JavaMail API, which is found in the package com.sun.mail.pop3, to interact with POP3 servers.

Installing JavaMail API

To use JavaMail API, you will need to add two jars in your CLASSPATH:

  1. mail.jar
  2. activation.jar.

If you are using Maven, Create a Maven Project referring to this link.

Note: JavaBeans Activation Framework (JAF) extension that provides the (activation.jar) javax.activation package is already present in Java SE 6 and later versions.

Send Emails

To send email, you will need an SMTP server. If you don't have an SMTP server, you can install one.

Here are a few tutorials to help you install an SMTP server on your machine:

Sample Code to Send Email Using SMTP

package com.sendemail;
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 SendMail {
    public static void main(String[] args) {
        // Mention the Recipient's email address
        String to = "[email protected]";
        // Mention the Sender's email address
        String from = "[email protected]";
        // Mention the SMTP server address. Below Gmail's SMTP server is being used to send email
        String host = "smtp.gmail.com";
        // Get system properties
        Properties properties = System.getProperties();
        // Setup mail server
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", "465");
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.auth", "true");
        // Get the Session object.// and pass username and password
        Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("[email protected]", "*******");
            }
        });
        // Used to debug SMTP issues
        session.setDebug(true);
        try {
            // Create a default MimeMessage object.
            MimeMessage message = new MimeMessage(session);
            // Set From: header field of the header.
            message.setFrom(new InternetAddress(from));
            // Set To: header field of the header.
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            // Set Subject: header field
            message.setSubject("This is the Subject Line!");
            // Now set the actual message
            message.setText("This is actual message");
            System.out.println("sending...");
            // Send message
            Transport.send(message);
            System.out.println("Sent message successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }
}

To facilitate a better understanding, let's dissect the code above into three parts.

#1. Getting the mail session:
The session is the context in which you will interact with the mail host. It is valuable for debugging output from the mail host, managing timeouts, and handling authentication mechanisms. The Session class offers two methods for obtaining the session object:

- getDefaultInstance(): Return default session.overloaded as below:

public static Session getDefaultInstance(Properties props)
public static Session getDefaultInstance(Properties props,Authenticator auth

- getInstance(): Returns new session.

public static Session getInstance(Properties props)
public static Session getInstance(Properties props,Authenticator auth)

The Authenticator class represents an object that understands how to obtain authentication for a network connection. To establish a session object, you must register the Authenticator with the session during the session's creation.

#2. Creating message content:
To create the message, you need to pass the session object in the MimeMessage class constructor:

MimeMessage message=new MimeMessage(session);

The message object will be used to store information
like from address, to address, subject and message body. InternetAddress represents an RFC 822 address.

#3. Transporting message over the selected protocol:
The Transport class serves as the message transport mechanism, utilizing the SMTP protocol to send an email message. That's it! You've successfully sent an email using the JavaMail API over SMTP. 

 

Errors while Sending Mail Using Java Mail API

#Error 1: Build Error javax.mail.internet.MimeMessage cannot be resolved.

Solution: This issue occurs when javax.mail.internet.MimeMessage is not found in your classpath. You can resolve this problem by adding it manually, or if you're using Maven for your project, you should include the necessary dependencies in your pom.xml file.

#Error 2: SendFailedException.getValidUnsentAddresses() not returning value as expected.

Solution: You need to enable property mail.smtp.reportsuccess and mail.smtp. send partial.

#Error 3: Unable to give multiple CC's

Solution: Use the below code:

    Address[] cc = new Address[] {InternetAddress.parse("[email protected]"),
                               InternetAddress.parse("[email protected]"), 
                               InternetAddress.parse("[email protected]")};
    message.addRecipients(Message.RecipientType.CC, cc);

#Error 4: Email sent through SMTP which contains German characters (umlauts) content is not displaying correctly.

Solution: You must set proper encoding for message subject and body as follow:

setContent(content, "UTF-8") 

The mail.mime.charset property typically defaults to using the Java charset, which is determined by the file.encoding property. The file.encoding property is set when the JVM starts up, but you can also configure it dynamically while running your Java program as follows:

java -Dfile.encoding=UTF-8 … com.x.Main

By this point, you should have explored a significant portion of the JavaMail API.

Important fact:
Oracle's Java JDK and JVM come with a paid licensing model. In contrast, the JavaMail API remains free and open source, made available under licenses such as the Common Development and Distribution License (CDDL) v1.1 and the GNU General Public License (GPL) v2 with Classpath Exception. This means developers can use the JavaMail API without incurring additional costs. Notably, the JavaMail API enjoys widespread usage in Android and Spring applications.

Let's see some examples of sending email using various properties of JavaMail API.

 

Send an email through SMTP without authentication.

Sample Code:

package com.sendemail;

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 SendMail {

    public static void main(String[] args) {

        // Mention the Recipient's email address
        String to = "[email protected]";

        // Mention the Sender's email address
        String from = "[email protected]";

        // Get system properties
        Properties properties = System.getProperties();

        // Setup mail server
        properties.put("mail.smtp.host", "smtp.host.com");
        properties.put("mail.smtp.port", "465");

        // Get the Session object and pass username and password
        Session session = Session.getInstance(properties);

        try {
            // Create a default MimeMessage object.
            MimeMessage message = new MimeMessage(session);

            // Set From: header field of the header.
            message.setFrom(new InternetAddress(from));

            // Set To: header field of the header.
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

            // Set Subject: header field
            message.setSubject("This is the Subject Line!");

            // Now set the actual message
            message.setText("This is actual message");

            System.out.println("sending...");
            // Send message
            Transport.send(message);
            System.out.println("Sent message successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }

    }

}

For the above code to work there should be no authentication at your SMTP server.

But in real life SMTP servers use authentication like TLS or SSL.
Let's check an example of setting TLS or SSL.

Send email using TLS and SSL authentication

To establish an SSL/TLS connection, applications using the JavaMail API (as the client) need to ensure that the client trusts the security certificate presented by the server. These trusted certificates are stored in a Java Keystore file on the client. This keystore acts as a repository for trusted certificates and enables the client to validate the server's identity and establish a secure connection. 

  1. Transport Layer Security (TLS) is a protocol that facilitates secure communication over a computer network. In the context of sending emails, TLS plays a crucial role in ensuring that the email communication between the sender and the email server is encrypted and secure. This encryption helps protect the confidentiality and integrity of the email content as it traverses the network.

    You need to set mail.smtp.starttls.enable to true. By default, 587 ports default to TLS.
    Here is a sample code:
package com.sendemail;
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 SendMail {

    public static void main(String[] args) {

        // Mention the Recipient's email addess
        String to = "[email protected]";

        // Mention the Sender's email address
        String from = "[email protected]";

        // Mention the SMTP server address. Below Gmail's SMTP server is being used to send email
        String host = "smtp.gmail.com";

        // Get system properties
        Properties properties = System.getProperties();

        // Setup mail server
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.auth", "true");

        // Get the Session object.// and pass username and password
        Session session = Session.getInstance(properties, new javax.mail.Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {

                return new PasswordAuthentication("[email protected]", "*******");

            }

        });

        // Used to debug SMTP issues
        session.setDebug(true);

        try {
            // Create a default MimeMessage object.
            MimeMessage message = new MimeMessage(session);

            // Set From: header field of the header.
            message.setFrom(new InternetAddress(from));

            // Set To: header field of the header.
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

            // Set Subject: header field
            message.setSubject("This is the Subject Line!");

            // Now set the actual message
            message.setText("This is actual message");

            System.out.println("sending...");
            // Send message
            Transport.send(message);
            System.out.println("Sent message successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }

    }
}

2. Using SSL
Secure Sockets Layer (SSL) is an older protocol for secure communication that has been succeeded by TLS. However, for compatibility with older systems, some services still support SSL. 

In earlier releases, it was necessary to explicitly set a socket factory property to enable the use of SSL. From Java Mail API 1.5 it is no longer needed, as the support for SSL is in-built. Note that for SSL, we use port 465 and specify the SSLSocketFactory class.

JavaMail API has a special SSL socket factory that can simplify dealing with servers with self-signed certificates.

class com.sun.mail.util.MailSSLSocketFactory can be used as a simple socket factory to allow trusting all or some hosts.

MailSSLSocketFactory avoids the need for managing the keystore or configuring your own TrustManager and adding a certificate in the Keystore.

Sample code:

package com.sendemail;

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 com.sun.mail.util.MailSSLSocketFactory;

public class SendMail {

    public static void main(String[] args) {

        // Mention the Recipient's email address
        String to = "[email protected]";

        // Mention the Sender's email address
        String from = "[email protected]";

        // Mention the SMTP server address. Below Gmail's SMTP server is being used to send email
        String host = "smtp.gmail.com";

        MailSSLSocketFactory sf = new MailSSLSocketFactory();
    sf.setTrustAllHosts(true);
    // or
    // sf.setTrustedHosts(new String[] { "my-server" });  

        // Get system properties
        Properties properties = System.getProperties();

        // Setup mail server
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.auth", "true");
        props.put("mail.smtp.ssl.socketFactory", sf);
        // Get the Session object.// and pass username and password
        Session session = Session.getInstance(properties, new javax.mail.Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {

                return new PasswordAuthentication("[email protected]", "*******");

            }

        });

        // Used to debug SMTP issues
        session.setDebug(true);

        try {
            // Create a default MimeMessage object.
            MimeMessage message = new MimeMessage(session);

            // Set From: header field of the header.
            message.setFrom(new InternetAddress(from));

            // Set To: header field of the header.
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

            // Set Subject: header field
            message.setSubject("This is the Subject Line!");

            // Now set the actual message
            message.setText("This is actual message");

            System.out.println("sending...");
            // Send message
            Transport.send(message);
            System.out.println("Sent message successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }

    }

}

 

Sending Inline Image in Email

Here is sample code :

package com.sendemail;

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
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.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class SendInlineImagesInEmail {
   public static void main(String[] args) {
      // Mention the Recipient's email address
      String to = "[email protected]";

      // Mention the Sender's email address
      String from = "[email protected]";
      final String username = "rishabhmishra131";//change accordingly
      final String password = "******";//change accordingly

      // Mention the SMTP server address. Below Pepipost's SMTP server is being used to send email
      String host = "smtp.pepipost.com";

      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 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 of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // This mail will have two parts, BODY and embedded image
         MimeMultipart multipart = new MimeMultipart("related");

         // first part (the html)
         BodyPart messageBodyPart = new MimeBodyPart();
         String htmlText = "<H1>Hello</H1><img src=\"cid:image-id\">";
         messageBodyPart.setContent(htmlText, "text/html");
         // add it
         multipart.addBodyPart(messageBodyPart);

         // second part (the image)
         messageBodyPart = new MimeBodyPart();
         DataSource fds = new FileDataSource(
            "/home/rishabh.mishra/sampleimage.png");

         messageBodyPart.setDataHandler(new DataHandler(fds));
         messageBodyPart.setHeader("Content-ID", "<image-id>");

         // add image to the multipart
         multipart.addBodyPart(messageBodyPart);

         // put everything together
         message.setContent(multipart);
         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");

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

Here, in this example, the image file has been used as an attachment. So, you have to set the Content-ID header for the image file and then use the same Content-ID in the email message body with:

<img src='cid:image-id'>

 
 Security Considerations

While both TLS and SSL provide encryption for email communication, it's important to note that SSL is considered less secure due to vulnerabilities found in older SSL versions. Therefore, using TLS is recommended for email communication whenever possible. Remember that using your password directly in the code is not secure, and it's recommended to use app-specific passwords or OAuth2 authentication for better security.

Common Errors/Exceptions with JavaMail API

JavaMail API has its own com.sun.mail.SMTP package for sending mail using SMTP protocol through which your program can access the SMTP server. The list for exception which com.sun.mail.smtp  throws is as follows :

  1. AuthenticationFailedException:
    Cause: Incorrect username or password for the email account.
    Solution: Double-check the email account credentials in your code. Make sure there are no typos or errors in the username and password.
  2. MessagingException (SMTPSendFailedException, SMTPAddressFailedException, etc.):
    Cause: Issues with the recipient's email address or the SMTP server.
    Solution: Verify that the recipient's email address is correctly formatted. Ensure that the SMTP server details, such as host and port, are accurate and that the server is reachable.
  3. AuthenticationFailedException or MessagingException with "Less Secure Apps" Error:
    Cause: If you are using your Gmail account for sending emails, "Less Secure Apps" may be disabled in your account settings.
    Solution: Enable "Less Secure Apps" in your Gmail account settings. Keep in mind that this method is less secure. For better security, consider using OAuth2 authentication.
  4. NoSuchProviderException:
    undefinedundefinedundefined
  5. MessagingException with "Could not connect to SMTP host: smtp.gmail.com, port: 587":
    undefinedundefined
  6. SMTPSendFailedException with "550 5.7.1 Relaying Denied":
    undefinedundefinedundefined
  7. **AuthenticationFailedException or MessagingException with "534-5.7.14":
    undefinedundefinedundefined
  8. **MailConnectException with "Couldn't connect to a host, port: smtp.gmail.com, 465; timeout":
    undefinedundefinedundefined
  9. **AuthenticationFailedException or MessagingException with "Authentication Required":
    undefinedundefinedundefined
  10. **MessagingException with "javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?":
    undefinedundefined

When encountering these errors, it's important to carefully read the error message, review your code, and verify your settings. In many cases, referring to the JavaMail documentation or online resources can help you troubleshoot and resolve the issues.

Few Examples :

- SMTPAddressFailedException :

com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Unable to relay

The error mentioned above is typically generated by the SMTP server and not JavaMail itself. It often occurs when your mail server is not set up to allow the sending of emails through it, as explained in the provided link: JavaMail FAQ.

To address this error and diagnose the issue, you can enable logging for your email client. Once you've enabled logging, you can review the logs for error details. You can share these logs with your email client administrator, who can assist in resolving the issue.

The JavaMail logs are typically written to the system OUT, which may be your catalina.out, localhost<xxx> file, or WEB-INF\logs\jasperserver.log, depending on your specific configuration. This logging mechanism helps in tracking and troubleshooting email-related problems.

- SMTPSendFailedException

com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required

The mentioned error often occurs when your SMTP user and password are incorrect or when you've updated the email configuration but have not reloaded the application server. This error is particularly common when sending emails through Gmail, as Google requires authentication for sending emails. It's important to ensure that the SMTP user credentials are accurate that any configuration changes are properly applied, and the application server is reloaded if necessary. This helps to prevent authentication-related issues when sending emails through services like Gmail.

We hope that this tutorial was useful. We are a community of email enthusiasts. If you have further queries, drop an email to [email protected], and we would be happy to help you.

Excited about the latest in Bulk Email Marketing! Check out this insightful blog on Gmail and Yahoo updates in the email marketing landscape.
Explore the Blog - Here
Stay ahead of the game with valuable insights on optimizing your email campaigns! 📬

Grade My Email
Check your spam now?

Netcorecloud's toolkit is the solution to all your email problems.

Rishabh Mishra

Programming Guy! Your coding problem corresponder.

You can also explore

Netcore connects & unifies your data across all sources, connects to your marketing channels and provides you with control over AI Powered automation and personalization.

Deploy emails that are
screenshot worthy!

Stop settling for static emails - use Netcore's platform to create dynamic, interactive emails that convert.
Let's Deploy
Get Started Now