JavaMail doesn’t actually send emails; it just formats them and hands them off to an SMTP server.

Let’s see it in action. Imagine you want to send a simple "Hello, world!" email from your Java application. Here’s the core setup:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

public class MailSender {

    public static void main(String[] args) {

        // Recipient's email ID
        String to = "recipient@example.com";

        // Sender's email ID
        String from = "sender@example.com";

        // Assuming you are sending email from localhost
        String host = "smtp.example.com"; // Your SMTP server hostname

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

        // Setup mail server
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "587"); // Standard TLS port
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.smtp.starttls.enable", "true"); // Enable STARTTLS

        // Get the Session object
        Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("sender@example.com", "your_password"); // Your email and password
            }
        });

        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 the actual message body of the email.");

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

This code snippet shows how you configure JavaMail to connect to an SMTP server (smtp.example.com in this case), authenticate with your credentials, and then send a simple text email. The Session object is the key here; it holds all the configuration for your mail session, including the SMTP host, port, and authentication details. The Transport.send(message) method is what actually pushes the formatted email to the SMTP server for delivery.

The fundamental problem JavaMail solves is abstracting away the complexities of the SMTP protocol. Instead of writing raw TCP/IP socket code to communicate with an SMTP server, you use a well-defined API. This API handles the SMTP commands (like HELO, MAIL FROM:, RCPT TO:, DATA, QUIT), MIME message formatting, and potentially SSL/TLS encryption. It lets you focus on what email you want to send (recipients, subject, body, attachments) rather than how to speak SMTP.

You control the process through the Properties object passed to Session.getInstance(). The mail.smtp.host and mail.smtp.port properties tell JavaMail which server to connect to and on which port. mail.smtp.auth set to true signals that authentication is required. Crucially, mail.smtp.starttls.enable set to true tells JavaMail to initiate a TLS handshake after connecting to the server, encrypting the subsequent communication. Without this, your credentials and email content would be sent in plain text, which is a huge security risk and often rejected by modern mail servers. The Authenticator inner class provides the username and password for this authentication.

The MimeMessage class is your canvas for constructing the email. You set the sender (setFrom), recipients (addRecipient), subject (setSubject), and the body (setText for plain text, or more complex methods for HTML and attachments). Once constructed, Transport.send(message) takes this MimeMessage and, using the Session’s configuration, establishes a connection to the SMTP server and transmits the email.

What most people don’t realize is how much the Session object, and specifically the Properties it’s initialized with, dictates the entire communication. You’re not just setting a hostname; you’re configuring the behavior of the SMTP client. For example, you might need mail.smtp.ssl.enable=true if the server requires an SSL connection from the very beginning (less common now than STARTTLS). The exact properties needed depend entirely on the SMTP server you’re connecting to. Your SMTP server might require a specific connection timeout (mail.smtp.connectiontimeout) or a socket timeout (mail.smtp.timeout), especially if it’s unreliable.

The next concept you’ll likely grapple with is handling email attachments, which involves using MimeBodyPart and Multipart objects to construct a more complex MIME structure.

Want structured learning?

Take the full Smtp course →