Skip to content

Java Sending Email

Sending email from a Java application requires using the Jakarta Mail API (formerly JavaMail). This API provides classes to compose, send, and receive emails using standard protocols like SMTP, POP3, and IMAP.

To use the Jakarta Mail API, you need to include its dependencies in your project. The modern way to manage dependencies is using a build tool like Maven or Gradle.

Maven Dependency (pom.xml):

<dependencies>
<!-- Jakarta Mail API -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version> <!-- Use the latest version -->
</dependency>
<!-- Jakarta Activation API (required by Jakarta Mail) -->
<!-- Use the runtime dependency provided by Angus -->
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-activation</artifactId>
<version>2.0.1</version> <!-- Use the latest version -->
</dependency>
</dependencies>

Gradle Dependency (build.gradle):

dependencies {
// Jakarta Mail API
implementation 'com.sun.mail:jakarta.mail:2.0.1' // Use the latest version
// Jakarta Activation API (required by Jakarta Mail)
// Use the runtime dependency provided by Angus
implementation 'org.eclipse.angus:angus-activation:2.0.1' // Use the latest version
}

Ensure you are using compatible and recent versions of these libraries.

To send email, you need to configure a Session object with properties for your mail server (SMTP host, port, authentication details).

Important: For real-world applications, avoid hardcoding credentials directly in the code. Use configuration files, environment variables, or secure credential management systems.

Example Configuration (using Gmail as SMTP server):

import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
// ... inside your class or method ...
final String username = "your_email@gmail.com"; // Your Gmail address
final String password = "your_app_password"; // Use an App Password for Gmail, NOT your regular password
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); // Gmail SMTP host
props.put("mail.smtp.port", "587"); // TLS port
props.put("mail.smtp.auth", "true"); // Enable authentication
props.put("mail.smtp.starttls.enable", "true"); // Enable STARTTLS
// Create a Session object with authenticator
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});

Note on Gmail App Passwords: If you use Gmail and have 2-Step Verification enabled, you must generate an “App Password” for your application instead of using your main Google account password. Search for “Sign in with App Passwords” in Google Account help.

Once you have a configured Session, you can create and send a MimeMessage.

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
// ... other imports including Session, Properties, etc. ...
public class SimpleEmailSender {
public static void main(String[] args) {
final String username = "your_email@gmail.com";
final String password = "your_app_password";
final String recipientEmail = "recipient@example.com";
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// Create a new email message
Message message = new MimeMessage(session);
// Set sender
message.setFrom(new InternetAddress(username));
// Set recipient
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(recipientEmail));
// Set subject
message.setSubject("Test Email from Java");
// Set content (plain text)
message.setText("Hello,\n\nThis is a simple test email sent from a Java application.");
// Send the message
Transport.send(message);
System.out.println("Email sent successfully!");
} catch (MessagingException e) {
System.err.println("Error sending email: " + e.getMessage());
e.printStackTrace();
}
}
}

Sending to Multiple Recipients:

You can specify multiple recipients using comma-separated addresses in InternetAddress.parse() or by adding recipients individually.

// Multiple TO recipients
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("recipient1@example.com, recipient2@example.com"));
// Adding CC or BCC recipients
message.addRecipients(Message.RecipientType.CC,
InternetAddress.parse("cc_recipient@example.com"));
message.addRecipients(Message.RecipientType.BCC,
InternetAddress.parse("bcc_recipient@example.com"));

To send HTML content, use the setContent() method with the appropriate MIME type (“text/html”).

// ... (session setup as before) ...
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail));
message.setSubject("HTML Test Email from Java");
// HTML content
String htmlContent = "<h1>Hello!</h1>"
+ "<p>This is an **HTML** email sent from Java.</p>"
+ "<p><a href='https://www.example.com'>Visit Example.com</a></p>";
// Set content as HTML
message.setContent(htmlContent, "text/html; charset=utf-8"); // Specify charset
Transport.send(message);
System.out.println("HTML Email sent successfully!");
} catch (MessagingException e) {
System.err.println("Error sending HTML email: " + e.getMessage());
e.printStackTrace();
}

It’s good practice to specify the character encoding (like utf-8) in the content type.

Sending attachments involves creating a multipart message (MimeMultipart) containing different body parts (MimeBodyPart) – one for the text/HTML body and others for attachments.

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
// ... other imports ...
// ... (session setup as before) ...
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail));
message.setSubject("Email with Attachment from Java");
// 1. Create the message body part (text or HTML)
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("Hello,\n\nPlease find the attached file.");
// Or for HTML: messageBodyPart.setContent(htmlContent, "text/html; charset=utf-8");
// 2. Create a multipart message container
Multipart multipart = new MimeMultipart();
// Add the text/HTML part to the multipart container
multipart.addBodyPart(messageBodyPart);
// 3. Create the attachment part
BodyPart attachmentBodyPart = new MimeBodyPart();
String filename = "path/to/your/file.txt"; // Specify the correct path to your file
DataSource source = new FileDataSource(filename);
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(source.getName()); // Use source.getName() to get the actual file name
// Add the attachment part to the multipart container
multipart.addBodyPart(attachmentBodyPart);
// --- Add more attachments similarly if needed ---
// 4. Set the multipart container as the message's content
message.setContent(multipart);
// 5. Send the message
Transport.send(message);
System.out.println("Email with attachment sent successfully!");
} catch (MessagingException e) {
System.err.println("Error sending email with attachment: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) { // Catch potential file handling errors
System.err.println("Error accessing attachment file: " + e.getMessage());
e.printStackTrace();
}

Ensure the file path in filename is correct and the application has permission to read the file.

  • Error Handling: Always wrap mail-sending code in a try-catch block to handle MessagingException and potentially other exceptions (like IO exceptions for attachments). Log errors appropriately.
  • Credentials: Never hardcode sensitive credentials. Use secure methods like environment variables, configuration files secured with appropriate permissions, or dedicated secrets management services.
  • Asynchronous Sending: For applications requiring responsiveness (like web applications), consider sending emails asynchronously using a separate thread or a message queue to avoid blocking the main application thread.
  • Connection Pooling: For high-volume sending, investigate connection pooling options if offered by your mail service or libraries built on top of Jakarta Mail.
  • Rate Limiting: Be aware of sending limits imposed by email providers (like Gmail) to avoid getting blocked.
  • Email Templates: For complex HTML emails, use templating engines (like Thymeleaf, Freemarker) to separate presentation from Java code.
  • Resource Management: Although Transport.send() often handles closing connections, if you manage Transport objects directly, ensure they are closed in a finally block or using try-with-resources if applicable.