Send an email in the internal application used for the notification system, e.g., monthly or weekly reports, an email with an attached file, or an email to an individual colleague with batch emails to subscribed clients.
The public application used for Registration Confirmation prevents invalid or nonexistent email addresses. Password Reset is used for users who forget their password and want to reset the password associated with their email.
Reports or Notifications
Scenario
The client wants reports monthly via email. The development team design generates reports as follows: process-generated reports in case of success or failure, and to create reports. The system will trigger the sending of an email process with information and the email format. If the generated report succeeds, the system will send an email with an attached file; otherwise, it will send a notification email that alerts the developer team and stakeholders to take care of the generated report failure.
Implement
The developer team created the process for sending an email with Jakarta Mail API libraries via SMTP so that the client receives monthly report information directly in their inbox.
Registration Confirmation
Scenario
Web applications allow users to create an account for any purpose.
The developer team must prevent invalid or nonexistent email addresses that require a confirmed email address. When the user registers, the system will send a confirmation email.
Implement
The developer team created a process to send an email with Jakarta Mail API libraries via SMTP so that users receive a confirmed email address.
Password Reset
Scenario
Web applications provide a password reset feature to support users who have forgotten their passwords. The email contains a link to change the password.
Implement
The development team has established a procedure for sending emails via SMTP, utilizing the Jakarta Mail API libraries. This process enables the transmission of a link to reset a password, which is dispatched to the email address associated with the user’s account registration.
Outlook
Outlook has made a significant change in how it sends emails. Instead of using the traditional SMTP (Simple Mail Transfer Protocol), Microsoft has shifted to using the Microsoft Graph API for sending emails.
Why the change?
- Security: Microsoft Graph supports more secure authentication methods like token-based authentication and conditional access policies.
- Deprecation of Basic Auth: Microsoft is phasing out Basic Authentication, which SMTP relies on.
- More Features: Graph allows not just sending emails but also accessing calendars, contacts, files, and more from Microsoft 365 — all in one unified API.
Example Gmail
public static void gmail() { final String username = "your_email@gmail.com"; final String password = "password"; //use password if disable two factor authentication. //use app password if enable two factor authentication. 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"); //TLS // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@gmail.com")); message.setSubject("Testing GmailSender"); message.setText("Dear User,\n\nThis is a test email sent from GmailSender."); // Send message Transport.send(message); System.out.println("Email sent successfully."); } catch (MessagingException e) { throw new RuntimeException(e); } }
If the application shows the error message “InvalidSecondFactor”, follow this instruction link. The developer needs to set the app password.
Google provides an API for accessing Gmail mailboxes and sending mail.

Example email with attached file
import jakarta.mail.*; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMultipart; import java.io.IOException; import java.util.Properties; public static void gmail() { final String username = "your_email@gmail.com"; final String password = "password"; 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"); //TLS // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@gmail.com")); message.setSubject("Testing GmailSender"); message.setText("Dear User,\n\nThis is a test email sent from GmailSender."); Multipart multipart = getMultipart(); // Set the multipart message content message.setContent(multipart); // Send message Transport.send(message); System.out.println("Email sent successfully."); } catch (MessagingException | IOException e) { throw new RuntimeException(e); } } private static Multipart getMultipart() throws MessagingException, IOException { String filePath = "monthly_report.pdf"; // Create the message body part BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("Please find the attached file."); // Create the attachment part MimeBodyPart attachmentPart = new MimeBodyPart(); attachmentPart.attachFile(filePath); // Combine the message body and attachment Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachmentPart); return multipart; }
Example email with multiple attached files
import jakarta.mail.*; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMultipart; import java.io.IOException; import java.util.Properties; public static void gmail() { final String username = "your_email@gmail.com"; final String password = "password"; 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"); //TLS // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@gmail.com")); message.setRecipients(Message.RecipientType.CC, InternetAddress.parse("cc@gmail.com")); //Carbon Copy message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse("bcc@gmail.com")); //Blind Carbon Copy message.setSubject("Testing GmailSender"); message.setText("Dear User,\n\nThis is a test email sent from GmailSender."); Multipart multipart = getMultipart(); // Set the multipart message content message.setContent(multipart); // Send message Transport.send(message); System.out.println("Email sent successfully."); } catch (MessagingException | IOException e) { throw new RuntimeException(e); } } private static Multipart getMultipart() throws MessagingException, IOException { List<String> filePaths = new ArrayList<>(Arrays.asList("monthly_report.pdf", "weekly_report.pdf", "yearly_report.pdf")); // Create the message body part BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("Please find the attached files."); // Create a multipart message Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // Attach files for (String filePath : filePaths) { MimeBodyPart attachmentPart = new MimeBodyPart(); attachmentPart.attachFile(filePath); multipart.addBodyPart(attachmentPart); } return multipart; }
For example, send an email to multiple recipients
public static void gmail() { final String username = "your_email@gmail.com"; final String password = "password"; //use password if disable two factor authentication. //use app password if enable two factor authentication. String[] recipientEmails = {"recipient1@example.com", "recipient2@example.com", "recipient3@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"); //TLS // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); // Add multiple recipients for (String recipientEmail : recipientEmails) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipientEmail)); } message.setSubject("Testing GmailSender"); message.setText("Dear User,\n\nThis is a test email sent from GmailSender."); // Send message Transport.send(message); System.out.println("Email sent successfully."); } catch (MessagingException e) { throw new RuntimeException(e); } }
For example, send an email with an attached file and encode it in Base64.
The developer is facing a problem when sending an email with an attachment, but the email hasn’t been sent for an unknown reason.
The developer can assume the file contains an invalid or forbidden character, such as an image or text file. When sending through HTTP, use Base64 Encoding to solve this problem.
import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.*; import javax.mail.internet.*; import java.io.*; import java.nio.file.Files; import java.util.Base64; import java.util.Properties; public class EmailWithBase64Attachment { public static void main(String[] args) { final String username = "example@example.com"; final String password = "password"; // SMTP server properties for Hotmail Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", "smtp-mail.outlook.com"); props.put("mail.smtp.port", "587"); // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); // Add multiple recipients String[] recipientEmails = {"recipient1@example.com"}; for (String recipientEmail : recipientEmails) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipientEmail)); } message.setSubject("Subject of the Email"); // Create the message part BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("This is the message body with an attachment."); // Create a multipart object Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // Add the attachment part BodyPart attachmentPart = new MimeBodyPart(); File file = new File("/path_to_file/image.png"); // Path to the file String base64EncodedFile = encodeFileToBase64(file); DataSource source = new ByteArrayDataSource(base64EncodedFile, "application/octet-stream"); attachmentPart.setDataHandler(new DataHandler(source)); attachmentPart.setFileName(file.getName()); multipart.addBodyPart(attachmentPart); // Set the multipart content to the message message.setContent(multipart); // Send the message Transport.send(message); System.out.println("Email sent successfully with Base64 encoded attachment."); } catch (MessagingException e) { e.printStackTrace(); } } // Encode file to Base64 public static String encodeFileToBase64(File file) { try { byte[] fileContent = Files.readAllBytes(file.toPath()); return Base64.getEncoder().encodeToString(fileContent); } catch (IOException e) { e.printStackTrace(); return null; } } // ByteArrayDataSource class to handle Base64 encoded data static class ByteArrayDataSource implements DataSource { private byte[] data; private String type; public ByteArrayDataSource(String data, String type) { this.data = Base64.getDecoder().decode(data); this.type = type; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(data); } @Override public OutputStream getOutputStream() throws IOException { throw new IOException("Not supported"); } @Override public String getContentType() { return type; } @Override public String getName() { return "ByteArrayDataSource"; } } }
Output.
Email sent successfully with Base64 encoded attachment.
Example subject and HTML encoding UTF-8
public static void outlook(){ final String username = "your_email@outlook.com"; final String password = "password"; // SMTP server properties for Hotmail Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", "smtp-mail.outlook.com"); props.put("mail.smtp.port", "587"); // Create session with authentication Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create message MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@outlook.com")); // Set UTF-8 encoded subject String subject = "Subject with UTF-8 Characters: こんにちは"; message.setSubject(subject, "UTF-8"); String htmlBody = "<html><body><p>Hello, this is an HTML email with UTF-8 characters: こんにちは</p></body></html>"; // Create the HTML body part BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(htmlBody, "text/html; charset=utf-8"); // Create a multipart message Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // Set the multipart message content message.setContent(multipart); // Send message Transport.send(message); System.out.println("Email sent successfully."); } catch (MessagingException e) { throw new RuntimeException(e); } }
Finally
Email sending can be integrated with the Quartz scheduler library or message queue to improve application design, which can trigger the send email process.