In this tutorial, we will discuss the way of sending emails from a Yahoo! Mail account using Javax Mail library. After taking a look at how to enable third party app access to Yahoo! Mail, we will see a Java project that will demonstrate how to send email and finally learn how to test. Though this tutorial is short, it will be useful in a lot of scenarios, e.g., setting up a notification service for a blog.
Introduction
It is very useful sometimes that a program can send email notifications to subscribers. I am sure all of us have done it. With .NET, it was very easy to create such a functionality with Outlook SMTP server. This tutorial will show you it is also easy to do. In addition, I want to show you how to connect to Yahoo! Mail account via SMTP and send an email to the same account. If you can send an email from and to the same account, you can use it to send any addresses.
After you learned how to send an email from your Yahoo! Mail account, please do not use it to spam someone else. Especially not to mass spam many people at once. If you do, I am sure you can get into trouble. Your Yahoo! Mail can be suspended, forcefully removed, or some other serious consequences may follow. Be warned.
Anyways, the same functionality can be used on a Google mail account. In fact, I got it working with a Google mail account before I changed the hard code account info to a Yahoo! Mail account. The reason I did that is security. With Google account, I had to go to my security configuration page to turn on the setting allowing 3rd party application to access my Google mail account. It was a simple switch that you can flip on and off. To me, this was not secure enough.
Yahoo! Mail, on the other hand, uses a more secure way to allow my application to access my own mail account. After I signed up a new account, I had to download Yahoo!'s mail application on my phone, and enable two factor authentication. Then I can get to my security configuration, enable my mail to allow 3rd party application to access. Here comes a twist, instead of a switch where I can turn on/off the mail access, I had to create a separated passcode for the 3rd party application. It is different from Google Mail, which means my primary password does not need to be exposed. With such difference, I feel Yahoo! Mail is just better when handling my account access. The downside is that Yahoo! Mail is saturated with advertisement. The only way to remove these is to upgrade to paid version. I am not too concerned with the ads, and only use the account to handle non-essential notifications.
In the next section, I will show you in detail how to configure a Yahoo! Mail account to enable 3rd party access.
Enable 3rd Party App Access to Yahoo! Mail
When I first worked on this, I thought it would be easy, connecting to the SMTP server would be using my user name and my primary password. I was surprised when I connected and got denied access. The repeated error was my user name and password mismatch. I realized I needed explicit authorization for 3rd party app access for my account only after some in-depth research. Below are the steps showing how you can enable such authorization.
If you have not signed up for an Yahoo! Mail account, you can sign up with user name, a good secure password, your day of birth, and optionally your gender. After signing up, you can provide a cell phone number, as well as another email address for password recovery. It is best to install Yahoo! Mail application afterwards and enable push authentication. If you don't do it, you will not able to authorize 3rd party application to access your Yahoo! Mail account.
First, you can login with your user name, then click Next.
If you have not signed in with your Yahoo! Mail application on your cell phone, you can log in with your primary password. If you have the Yahoo! Mail, then you will see your mail account home page. Like this:
Go to the upper right corner of the page, and you will find your user name. It is a clickable field.
Click it and you will see a dropdown, like this:
In the dropdown, one link is called "Account Info". Click to access it.
After clicking it, you will be asked to log in again to see the "Account Security" page. Once logged in, you will see the following page:
At the very bottom, you will see the "Manage app passwords". Click it.
As you can see from this screenshot, the popup displays a list of applications that has access to this Yahoo! mail account. I have already added one, as shown in the list. Click on "Select your app" to pop up the drop down, like this:
At the very bottom of the dropdown list, find the option "Other App". Select it. The dropdown becomes a text box, where you can enter a name. Like this:
Enter a meaningful name and click "Generate". This will generate a passcode and associate with a name. Like this:
Once you get the passcode, you must write it down somewhere that you can access later, because if you click "Done", you are never going to see this passcode again. Don't lose it.
Once you saved the passcode, click "Done", you will be all set.
The most important part of this tutorial is done. Next, we will go over the project code.
Java Project to Send Email with Yahoo! Mail
For this tutorial, I like to keep it simple. The project has one public
class. Inside, there is the main entry method. The whole process of connecting to SMTP, creating the email content, and sending out, can all be found in this method. I started out with Maven POM file. I use it to create Eclipse project. Finally, I import the project into Eclipse. From Eclipse, I write the code, and run it within. The point is, once you know how to do it all in one shot, you can refactor it into a utility class and integrate with your project.
The POM XML File
The Maven POM file can be found in the associated source files section. I don't want to waste too much time on this file's content. The only thing I like to discuss is the dependency needed for this project -- the Javax Mail library.
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
This is the only dependency you needed. And it would force download some more dependencies. What is confusing about this is the fact there is another dependency, the artifact-id
is javax.mail-api
. If you tried to run this program with this wrong dependency, you will get a runtime exception. This library javax.mail-api
has only the interface for Javax Mail, no implementation, which is why the program will not work.
Next, we will look at the source code.
Java Source Code
The Java source code for this program is straight forward. Here is the entire program:
package org.hanbo.yahoo.mail.sample;
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 App
{
public static void main(String[] args)
{
final String to = "nobunagX.XXXXXXX@yahoo.com";
final String from = "nobunagX.XXXXXXX@yahoo.com";
String host = "smtp.mail.yahoo.com";
Properties properties = System.getProperties();
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");
Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("nobunagX.XXXXXXX", "XXXXgdflXXXXinta");
}
});
session.setDebug(true);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
System.out.println("sending...");
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
Let's take a look at this line by line. First, I declared two local variables that represent the from
and to
addresses for the email to sent:
final String to = "nobunagX.XXXXXXX@yahoo.com";
final String from = "nobunagX.XXXXXXX@yahoo.com";
The two addresses are the same because I want to send the mail from me to myself, not to spam someone else. Next, I will create a properties collection to put some key/value pairs in it. They are references of the Yahoo! Mail server info:
String host = "smtp.mail.yahoo.com";
Properties properties = System.getProperties();
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");
There are a couple things to be noted here:
- The mail host is
smtp.mail.yahoo.com
. - The port number is
587
. There is another port number, that, is for legacy SSL connections. You should not use it. See next port for the reason. mail.smtp.starttls.enable
is set to true
. I believe this option enables the TLS for the data transportation. This is more secure than the SSL transportation. Hence, you should use this along with port number 587
, instead of the SSL and a different port number. SSL will eventually be deprecated. - The last one specifies that authentication in order to establish connection.
The next step is create a mail session object. When I declared the session
object, I also specified the user name and password to the Yahoo! Mail server. This is where I put my user name without the suffix of "@yahoo.com
", and the password, is the passcode I have generated on my Account Info page. This is not the primary password when I signed up the mail service:
Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("nobunagX.XXXXXXX", "XXXXgdflXXXXinta");
}
});
session.setDebug(true);
When you run the test, you want to replace the user name and password with your user name and password.
Setting debug mode on the session object will make trouble shooting easier. Operation wise, it serve little purpose.
Here is the code that creates a mail message, which takes the session
object. This is different from how .NET mail API works. I guess when the mail is sent, the session
will be created. Once the mail reaches the server, the session
will be closed:
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
Finally, the following code will send the message:
System.out.println("sending...");
Transport.send(message);
System.out.println("Sent message successfully....");
That is all there is to send an email with Yahoo! Mail service.
How to Test
To build the application, run the following command:
mvn clean install
To create the Eclipse project, run the following command:
mvn eclipse:eclipse
If you can import the project into Eclipse, you can expand the project, and find where the Java file is. Select it and right click on it, then select "Run As"->"Java Application".
To run this with Maven, use the following command:
mvn exec:java -Dexec.mainClass="org.hanbo.yahoo.mail.sample.App"
As long as it can be built successfully, you should be able to run the program. Here is the extended output log showing email has been sent successfully.
DEBUG: setDebug: JavaMail version 1.6.2
sending...
DEBUG: getProvider() returning javax.mail.Provider
[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.mail.yahoo.com,
user={{XXXXXXX}}, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.mail.yahoo.com", port 587, isSSL false
220 smtp.mail.yahoo.com ESMTP ready
DEBUG SMTP: connected to host "smtp.mail.yahoo.com", port: 587
EHLO XXXXXXXXXXXX
250-smtp429.mail.gq1.yahoo.com Hello {{XXXXXXXXXXXX}} [xxx.xxx.xxx.xxx])
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-SIZE 41697280
250 STARTTLS
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "41697280"
DEBUG SMTP: Found extension "STARTTLS", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO XXXXXXXXXXXX
250-smtp429.mail.gq1.yahoo.com Hello XXXXXXXXXXXX [xxx.xxx.xxx.xxx])
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-SIZE 41697280
250 AUTH PLAIN LOGIN XOAUTH2 OAUTHBEARER
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "41697280"
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN XOAUTH2 OAUTHBEARER"
DEBUG SMTP: protocolConnect login, host=smtp.mail.yahoo.com,
user=nobunagX.XXXXXXX, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<nobunagX.XXXXXXX@yahoo.com>
250 2.1.0 Sender <nobunagX.XXXXXXX@yahoo.com> OK
RCPT TO:<nobunagX.XXXXXXX@yahoo.com>
250 2.1.5 Recipient <nobunagX.XXXXXXX@yahoo.com> OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: nobunagX.XXXXXXX@yahoo.com
DATA
354 Ok Send data ending with <CRLF>.<CRLF>
Date: Tue, 21 Apr 2020 23:28:50 -0400 (EDT)
From: nobunagX.XXXXXXX@yahoo.com
To: nobunagX.XXXXXXX@yahoo.com
Message-ID: <1880587981.0.1587526130394@XXXXXXXXXXXX>
Subject: This is the Subject Line!
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
This is actual message
.
250 OK , completed
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Service Closing transmission
Sent message successfully....
Check the Yahoo! Mail inbox, and you should see something like this:
Summary
This is a short tutorial on Javax mail library. As shown, Javax mail library is a really easy to use library. When I first started this, and got it working, I thought the whole setup is very cool, worthy of documenting. Hence, there is this tutorial. The hard part was figuring out the Yahoo! Mail security configuration.
This tutorial is not much, but will be useful in a lot of scenarios. For example, one can set up a notification service for your blog. Whenever a comment is added for a post you have published, it can send a mail to notify you. Or you can set up an AI service that monitors stocks, whenever the stocks are hitting a good price, the service can send you an email. There are many other scenarios that also make sense with such functionality. This tutorial enables you to create such functionality with ease. I hope you will find this useful.
Thanks for visiting...
History
- 21st April, 2020 - Initial draft