Today we will look into JavaMail Example to send email in java programs. Sending emails is one of the common tasks in real life applications and that’s why Java provides robust JavaMail API that we can use to send emails using SMTP server. JavaMail API supports both TLS and SSL authentication for sending emails.
Today we will learn how to use JavaMail API to send emails using SMTP server with no authentication, TLS and SSL authentication and how to send attachments and attach and use images in the email body. For TLS and SSL authentication, I am using GMail SMTP server because it supports both of them. You can also choose to go for a Java mail server depending on your project needs. JavaMail API is not part of standard JDK, so you will have to download it from it’s official website i.e JavaMail Home Page. Download the latest version of the JavaMail reference implementation and include it in your project build path. The jar file name will be javax.mail.jar. If you are using Maven based project, just add below dependency in your project.
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
Java Program to send email contains following steps:
javax.mail.Session
objectjavax.mail.internet.MimeMessage
object, we have to set different properties in this object such as recipient email address, Email Subject, Reply-To email, email body, attachments etc.javax.mail.Transport
to send the email message.The logic to create session differs based on the type of SMTP server, for example if SMTP server doesn’t require any authentication we can create the Session object with some simple properties whereas if it requires TLS or SSL authentication, then logic to create will differ. So I will create a utility class with some utility methods to send emails and then I will use this utility method with different SMTP servers.
Our EmailUtil class that has a single method to send email looks like below, it requires javax.mail.Session and some other required fields as arguments. To keep it simple, some of the arguments are hard coded but you can extend this method to pass them or read it from some config files.
package com.journaldev.mail;
import java.io.UnsupportedEncodingException;
import java.util.Date;
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.Multipart;
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 EmailUtil {
/**
* Utility method to send simple HTML email
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendEmail(Session session, String toEmail, String subject, String body){
try
{
MimeMessage msg = new MimeMessage(session);
//set message headers
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setText(body, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
System.out.println("Message is ready");
Transport.send(msg);
System.out.println("EMail Sent Successfully!!");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Notice that I am setting some header properties in the MimeMessage, they are used by the email clients to properly render and display the email message. Rest of the program is simple and self understood. Now let’s create our program to send email without authentication.
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Session;
public class SimpleEmail {
public static void main(String[] args) {
System.out.println("SimpleEmail Start");
String smtpHostServer = "smtp.example.com";
String emailID = "email_me@example.com";
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHostServer);
Session session = Session.getInstance(props, null);
EmailUtil.sendEmail(session, emailID,"SimpleEmail Testing Subject", "SimpleEmail Testing Body");
}
}
Notice that I am using Session.getInstance() to get the Session object by passing the Properties object. We need to set the mail.smtp.host property with the SMTP server host. If the SMTP server is not running on default port (25), then you will also need to set mail.smtp.port property. Just run this program with your no-authentication SMTP server and by setting recipient email id as your own email id and you will get the email in no time. The program is simple to understand and works well, but in real life most of the SMTP servers use some sort of authentication such as TLS or SSL authentication. So we will now see how to create Session object for these authentication protocols.
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class TLSEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for TLS/STARTTLS: 587
*/
public static void main(String[] args) {
final String fromEmail = "myemailid@gmail.com"; //requires valid gmail id
final String password = "mypassword"; // correct password for gmail id
final String toEmail = "myemail@yahoo.com"; // can be any email id
System.out.println("TLSEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //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 Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getInstance(props, auth);
EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
}
}
Since I am using GMail SMTP server that is accessible to all, you can set the correct variables in above program and run for yourself. Believe me it works!! :)
package com.journaldev.mail;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
public class SSLEmail {
/**
Outgoing Mail (SMTP) Server
requires TLS or SSL: smtp.gmail.com (use authentication)
Use Authentication: Yes
Port for SSL: 465
*/
public static void main(String[] args) {
final String fromEmail = "myemailid@gmail.com"; //requires valid gmail id
final String password = "mypassword"; // correct password for gmail id
final String toEmail = "myemail@yahoo.com"; // can be any email id
System.out.println("SSLEmail Start");
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
props.put("mail.smtp.port", "465"); //SMTP Port
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
};
Session session = Session.getDefaultInstance(props, auth);
System.out.println("Session created");
EmailUtil.sendEmail(session, toEmail,"SSLEmail Testing Subject", "SSLEmail Testing Body");
EmailUtil.sendAttachmentEmail(session, toEmail,"SSLEmail Testing Subject with Attachment", "SSLEmail Testing Body with Attachment");
EmailUtil.sendImageEmail(session, toEmail,"SSLEmail Testing Subject with Image", "SSLEmail Testing Body with Image");
}
}
The program is almost same as TLS authentication, just some properties are different. As you can see that I am calling some other methods from EmailUtil class to send attachment and image in email but I haven’t defined them yet. Actually I kept them to show later and keep it simple at start of the tutorial.
To send a file as attachment, we need to create an object of javax.mail.internet.MimeBodyPart
and javax.mail.internet.MimeMultipart
. First add the body part for the text message in the email and then use FileDataSource to attach the file in second part of the multipart body. The method looks like below.
/**
* Utility method to send email with attachment
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendAttachmentEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
// Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText(body);
// Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Second part is attachment
messageBodyPart = new MimeBodyPart();
String filename = "abc.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
msg.setContent(multipart);
// Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with attachment!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
The program might look complex at first look but it’s simple, just create a body part for text message and another body part for attachment and then add them to the multipart. You can extend this method to attach multiple files too.
Since we can create HTML body message, if the image file is located at some server location we can use img element to show them in the message. But sometimes we want to attach the image in the email and then use it in the email body itself. You must have seen so many emails that have image attachments and are also used in the email message. The trick is to attach the image file like any other attachment and then set the Content-ID header for image file and then use the same content id in the email message body with <img src='cid:image_id'>
.
/**
* Utility method to send image in email body
* @param session
* @param toEmail
* @param subject
* @param body
*/
public static void sendImageEmail(Session session, String toEmail, String subject, String body){
try{
MimeMessage msg = new MimeMessage(session);
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress("no_reply@example.com", "NoReply-JD"));
msg.setReplyTo(InternetAddress.parse("no_reply@example.com", false));
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
// Create the message body part
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
// Create a multipart message for attachment
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Second part is image attachment
messageBodyPart = new MimeBodyPart();
String filename = "image.png";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
//Trick is to add the content-id header here
messageBodyPart.setHeader("Content-ID", "image_id");
multipart.addBodyPart(messageBodyPart);
//third part for displaying image in the email body
messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent("<h1>Attached Image</h1>" +
"<img src='cid:image_id'>", "text/html");
multipart.addBodyPart(messageBodyPart);
//Set the multipart message to the email message
msg.setContent(multipart);
// Send message
Transport.send(msg);
System.out.println("EMail Sent Successfully with image!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
java.net.UnknownHostException
comes when your system is not able to resolve the IP address for the SMTP server, it might be wrong or not accessible from your network. For example, GMail SMTP server is smtp.gmail.com and if I use smtp.google.com, I will get this exception. If the hostname is correct, try to ping the server through command line to make sure it’s accessible from your system.
pankaj@Pankaj:~/CODE$ ping smtp.gmail.com
PING gmail-smtp-msa.l.google.com (74.125.129.108): 56 data bytes
64 bytes from 74.125.129.108: icmp_seq=0 ttl=46 time=38.308 ms
64 bytes from 74.125.129.108: icmp_seq=1 ttl=46 time=42.247 ms
64 bytes from 74.125.129.108: icmp_seq=2 ttl=46 time=38.164 ms
64 bytes from 74.125.129.108: icmp_seq=3 ttl=46 time=53.153 ms
If your program is stuck in Transport send() method call, check that SMTP port is correct. If it’s correct then use telnet to verify that it’s accessible from you machine, you will get output like below.
pankaj@Pankaj:~/CODE$ telnet smtp.gmail.com 587
Trying 2607:f8b0:400e:c02::6d...
Connected to gmail-smtp-msa.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP sx8sm78485186pab.5 - gsmtp
HELO
250 mx.google.com at your service
That’s all for JavaMail example to send mail in java using SMTP server with different authentication protocols, attachment and images. I hope it will solve all your needs for sending emails in java programs.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Thank you! Your example is very helpful.
- Lily
I am using java and javax.mail to send email messages via Mandrill (Mailchimps transactional email). mandrill allows us to specify a subaccount in their platform. They say I need to: Customize messages with SMTP headers You can use SMTP headers to customize your messages, add tracking, or specify options for Mailchimp Transactional to apply to your emails. How you set the headers is dependent upon your environment; read the documentation for your tools for more information on how to set SMTP headers. That’s where I found this for specifying the subaccount. X-MC-Subaccount Set a subaccount Purpose Select a subaccount for sending mail. Format • The unique ID of the subaccount for the message • The subaccount must exist—otherwise, the mail will be accepted by the SMTP server but ultimately fail to send. Example X-MC-Subaccount: my_subaccount How do I specify a smtp header from Java and using the javax.mail package?
- David Gonynor
What changes will need to be done if I want to send many email in a single session?
- Dinesh Solanki
hi pankaj, when i use this i’m getting - unable to find valid certification path to requested target, can you help me with this
- jagadeeswar
Hello Mstr @Pankaj , I would thank you first for this useful tutoriel , and ask you a queqtion if you don’t mind: I used the SMTP via TLS configurtion, in the bigenning it doesn’t work but when I enabled Less Secure App and in Local it works very well .But the problem appears again when I build my work is remoted in the Server of the Company. Here is the error : “timestamp”: 1586528739449, “status”: 500, “error”: “Internal Server Error”, “exception”: “javax.mail.AuthenticationFailedException”, “message”: “534-5.7.14 \n534-5.7.14 Please log in via your web browser and then try again.\n534-5.7.14 Learn more at\n534 5.7.14 https://support.google.com/mail/answer/78754 f2sm3094546wro.59 - gsmtp\n”, “path”: “/api/mailing/sendMail” } Thank uou so much for your help :) .
- Brigui Malek
Hello every one I have run the code then I get this error says that: run: SimpleEmail Start Exception in thread “main” java.lang.ExceptionInInitializerError at com.journaldev.mail.SimpleEmail.main(SimpleEmail.java:23) Caused by: java.lang.RuntimeException: Uncompilable source code - class EmailUtil is public, should be declared in a file named EmailUtil.java at com.journaldev.mail.EmailUtil.(EmailUtil_1.java:21) … 1 more C:\Users\HP\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1 BUILD FAILED (total time: 0 seconds) I need help to solve that error and I need to make a forgot password with email in jsp so you may help me ?
- Theophile
my code is working fine with local machine but when i host the website and my functionality it is not working. there is parsing issue at server side. I didn’t get the issue. please help!
- Rutuja
This is a great start for developers new to emailing in Java, but dealing with javax JavaMail (nowadays migrated to Jakarta Mail) is very low level. Depending on your combination of needs (embedded images, attachments, iCalendar integration, forwarded email, replied-to email, alternative content) you need different Mime structures to have proper email behavior across email clients. You can explore all those structures here: https://www.simplejavamail.org/rfc-compliant.html#section-explore-multipart Simple Java Mail (https://www.simplejavamail.org) is an open source library that manages these structures for you. It has a much simpler API and simplifies configuration for SSL/TLS connections. In addition, it adds tons of capabilities such as authenticated proxy, encryption, batch processing and much more. People really shouldn’t be dealing with Mime objects anymore in this day and age. It’s an archaic system that is poorly described in terms of which structure to apply for which combination of needs. This includes most libraries such as Apache, Spring and JavaMail itself. Simple Java Mail solves this problem entirely free of cost.
- Benny Bottema
hello using this code i am being able to send emails to only yaahoo acc. How will i be able to send mails to all acc?
- bhav
Hello, do you know the algorithm how to send email with Imge in spesific size , I mean while Image size > 2MB then the response is “Sorry, your image are to large / more than 2 MB” thank you. :)
- Dewa