Welcome!

Java IoT Authors: Liz McMillan, Yeshim Deniz, Elizabeth White, Zakia Bouachraoui, Pat Romanski

Related Topics: Java IoT

Java IoT: Article

What is JavaMail?

What is JavaMail?

JavaMail is a set of abstract classes that create a framework for sending, receiving and handling e-mail, along with implementations of those classes. The package Sun provides contains implementations of IMAP and SMTP, allowing you to get started immediately on sending and receiving mail. They also provide a separate POP3 implementation that I'll describe below. The framework makes it easy to create your own cross-platform mail application without an in-depth knowledge of e-mail. Methods and classes that allow you to access mail folders, download messages, send messages with attachments and filter mail are included.

JavaMail has a number of uses in personal and Enterprise-level programming. It can be used to create personal mail filters, simple mailing lists and customized personal mail applications, as well as to add full e-mail capabilities to an Enterprise application or create a full-fledged e-mail client. A number of products currently available are built for or around JavaMail; many are listed on the JavaMail Third Party Product page (http://java.sun.com/products/javamail/Third_Party.html). Several companies have written marketing applications that use JavaMail to send customized mail to groups of contacts, and many companies have written new e-mail clients using JavaMail and its extensions.

Background
Knowing a little about what e-mail is and how it is sent and received is helpful in creating e-mail applications. E-mail protocols are, in the most basic sense, a way of transferring data from one machine to another, possibly going through several other machines along the way. SMTP has existed, essentially in its current state, since the early 1980s, and POP and IMAP aren't much younger. The preceding is a very basic introduction to these protocols; see "Where to get more information" for more information.

SMTP - Simple Mail Transfer Protocol - allows two mail servers to communicate using a simple language, and provides a step-by-step protocol for exchanging information. To use the example that follows, you'll need an SMTP server. If you're using UNIX, you probably have one on your machine already. If you're not, or don't have a server installed, you can ask your system administrator for the name of your SMTP server.

IMAP - Internet Mail Access Protocol - and POP3 - Post Office Protocol Version 3 - are client/server mail protocols. SMTP delivers mail to a central location, where the user can either log in and read it directly or use a client/server mail protocol to read it remotely. IMAP is designed to keep mail on a remote server and let the user interact with it there, while POP3 is designed to forward a user's mail to a single machine, where the user can go offline and read it, if necessary. In general, people with slow connections (dial-up or otherwise) tend to use POP3 because they can connect and download their mail without having to keep the connection open afterwards. People with fast connections and multiple machines usually use IMAP so they can read mail from whichever machine they happen to be on without losing access to the mail they read elsewhere. In the following examples, you will need a POP3.

How Do I Get Started?
First, you'll need the JDK (I use 1.2 in this article), JavaMail package and the JavaBeans Activation Framework extension (JAF). JAF is a standard extension that provides a way to identify and correctly process unknown data. You can download each from the Java Web site. JDK 1.2 (also known as the Java 2 SDK) is at http://java. sun.com/products/jdk/1.2/, and JavaMail and JAF are at http:/ /java.sun.com/products/ javamail/index.html. Follow the installation instructions given on the download pages, and install the packages. JavaMail comes with a number of examples in the demo directory, many of which are easy to use immediately or can be modified for specific situations.

A simple example is msgsendsample.java. This sends a simple message (included in the example) to an e-mail address provided by the user. To use this, go to the demo directory and compile msgsendsample.java. Then, on the command line, type:

  java msgsendsample <your email address> <your email address> <your SMTP server> false
e.g.
  java msgsendsample [email protected] [email protected] smtp.silentq.com false

The command line arguments are <address to> <address from> <mail server> <debug>. You can actually specify any e-mail address for the from argument and the message will appear to be from that e-mail address, but a look at the full headers will show the real source. The false at the end indicates that you don't want to see the debug information; change that to true for a look at what the example is doing. The complete SMTP connection dialog will be printed out, as well as some debug information for the example.

A look at the source shows how this example works:

Properties props = new Properties();
props.put("mail.smtp.host", host);

JavaMail needs the mail host property set to determine where the SMTP server is located. If it's on your local machine, the send can happen locally. Otherwise it will automatically connect to the server machine and send from there.

Session session = Session.getDefaultInstance(props, null);

This gets a mail session (notice it uses the properties just created). The default mail session is created if it doesn't already exist, and permissions are created or checked. Since the Authenticator (security object - the second parameter listed) is null, there's no security on this object, and anyone can access it.

Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
  InternetAddress[] address = {new InternetAddress(args[0])};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("JavaMail APIs Test");
msg.setSentDate(new Date());
msg.setText(msgText);

This section creates the actual message object and fills in the to, from, subject, date and content. There are also options to set the reply to, content and content type, and other header information. Since this is a MIME - Multipurpose Internet Mail Extensions - message, it can have several parts, none of which have to be plain text. You may want to set a section to HTML or add an attachment. You can set a DataHandler (in the JDK) using setDataHandler() in MimeMessage to handle nontext parts. This is a simple one-part text message, so you can use the setText() method instead.

Transport.send(msg);

This actually sends the message, using SMTP. If the send fails, it will throw exceptions based on the problem with the send. For example, try sending to a nonexistent address for example, ("rachelfoo"). You'll see a SendFailedException, with some details about the address that failed.

With a few changes you can modify this example to send mail programmatically. Changing the <to>, <from>, <host>, <subject> and <content> values to method arguments and adding a constructor to set them will allow you to instantiate this object from another class and send mail automatically. In addition, you can add a hashtable of substitutions and include these in your message text to personalize the e-mail - see Listing 1. This listing creates the hashtable individually for each e-mail, but this could be customized to read from a database or file.

A More Complex Code Sample
The next example will read and optionally delete messages from a POP3 server. The first step is to download and install a POP3 provider. The example uses Sun's POP3 provider. Follow the directions from the JavaMail page at Sun (listed above) to download and unzip the package, and set your classpath correctly. Since you may want to use other providers later, you need to add this provider to your provider list. To do this, create a new directory, copy the mail.jar file into that directory and unjar it (jar xvf mail.jar).

You'll see several directories, including a META-INF directory, which generally contains information about the jar file that includes it, but in this case also contains information critical to JavaMail. This is important to remember. If you ever install JavaMail as part of a product, be sure to include this directory in your product package.

To add the POP3 provider, create a file called javamail.providers with the following line in it:

protocol=pop3; type=store; class=com.sun.mail.pop3.POP3Store;

Then jar the directories again (jar cvf mail.jar *), back up the old mail.jar and move the new mail.jar into place. You now have a POP3 provider added to your provider list.

The POP3 example is included here as Listing 2. Download and compile the program - you'll need a POP3 mail server to test it. The example takes parameters <username> <password> <server> <delete>. The last parameter specifies whether you want to delete any messages you read from the server. Test the program with:

  java MailPrinter <your POP3 username> <your POP3 password> <your POP3 mail server> false
e.g.   java MailPrinter rachel mypassword pop3.silentq.com false

You'll see a list of all your new messages with their headers. The thread will continue, downloading all messages every five minutes until you stop it. This could easily be changed to append to a file; with the delete option set to true, it would constantly update your local mail file. It could also be altered simply to check the number of messages and, with a small user interface, could be made into a mail notification system.

The source can be broken down as follows:

Properties lProperties = System.getProperties();

Session lSession = Session.getDefaultInstance(lProperties, null);

As in the last example, the session is started with no security. This time it's started with the system properties instead of an empty Properties object.

Store store = null;
Folder folder = null;
try {
   store = lSession.getStore(protocol); }

This part gets the store type for the given protocol (POP3). Store is an abstract class that models a message store. This allows connections to various types of actual message stores with no loss of generality.

store.connect(host, user, password);

Now it connects to the remote server (host) with the given username and password. Obviously, it would be unwise to do this part programmatically without a fair number of precautions - storing your password in plain text in the source is a security problem. It might be wise to store the password encrypted in your database or file system and retrieve and unencrypt it only when needed.

folder = store.getDefaultFolder();  ...  folder = folder.getFolder("INBOX");

This initializes the folder with the standard default mailbox, indicated by the key word "INBOX". In this context INBOX stands for "primary folder for this user on this server" - it will vary by protocol, server and user.

folder.open(Folder.READ_WRITE);  ...  Message[] messages = folder.getMessages();

Here the folder is opened and the messages are downloaded. This includes their headers and all parts of the message (in the case of MIME messages). This doesn't remove them from the server; it just copies them into memory.

if (delete)     messages[i].setFlag(Flags.Flag.DELETED, true);
...
folder.close(true);
store.close();

Flags indicate the status of the message in the folder. Here each downloaded message is marked deleted, and when the folder is closed the "true" flag indicates that all deleted messages should be removed.

 for (Enumeration e = pPart.getAllHeaders(); e.hasMoreElements(); )
{     Header header = (Header) e.nextElement();
   System.out.println(header.getName() + ": " + header.getValue());
}

This section gets each of the header lines from the message and prints them out. You could change this part to print out only the headers you're interested in using: getMatchingHeaders() instead of getAllHeaders().

The rest of the example recursively divides the message into parts and prints each part. This example could easily be expanded to filter out messages with selected subjects or messages from particular addresses. It could store the messages in a database or to a file. In all, JavaMail gives you powerful tools to filter and manipulate e-mail messages with very simple code.

For More Information
1. JavaMail home page: http://java.sun.com/products/javamail/index.html
2. RFC 821 (SMTP specification:http://info.internet.isi.edu/in-notes/rfc/files/rfc821.txt
3. IMAP, POP3: ftp://ftp.cac.washington.edu/mail/imap.vs.pop For anything not covered in these sources, a simple Net search will probably find what you need. E-mail is a frequently discussed topic on the Net, and there are FAQs and articles everywhere. Good luck!

More Stories By Rachel Gollub

Rachel Gollub, founder of SilentQ Software Company, learned Java as a JavaSoft engineer from 1995 to 1997, and has worked at several start-ups since then. She writes articles and gives presentations on Java and related subjects

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
SYS-CON Events announced today that Silicon India has been named “Media Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Published in Silicon Valley, Silicon India magazine is the premiere platform for CIOs to discuss their innovative enterprise solutions and allows IT vendors to learn about new solutions that can help grow their business.
We are seeing a major migration of enterprises applications to the cloud. As cloud and business use of real time applications accelerate, legacy networks are no longer able to architecturally support cloud adoption and deliver the performance and security required by highly distributed enterprises. These outdated solutions have become more costly and complicated to implement, install, manage, and maintain.SD-WAN offers unlimited capabilities for accessing the benefits of the cloud and Internet. ...
Founded in 2000, Chetu Inc. is a global provider of customized software development solutions and IT staff augmentation services for software technology providers. By providing clients with unparalleled niche technology expertise and industry experience, Chetu has become the premiere long-term, back-end software development partner for start-ups, SMBs, and Fortune 500 companies. Chetu is headquartered in Plantation, Florida, with thirteen offices throughout the U.S. and abroad.
SYS-CON Events announced today that CrowdReviews.com has been named “Media Sponsor” of SYS-CON's 22nd International Cloud Expo, which will take place on June 5–7, 2018, at the Javits Center in New York City, NY. CrowdReviews.com is a transparent online platform for determining which products and services are the best based on the opinion of the crowd. The crowd consists of Internet users that have experienced products and services first-hand and have an interest in letting other potential buye...
Business professionals no longer wonder if they'll migrate to the cloud; it's now a matter of when. The cloud environment has proved to be a major force in transitioning to an agile business model that enables quick decisions and fast implementation that solidify customer relationships. And when the cloud is combined with the power of cognitive computing, it drives innovation and transformation that achieves astounding competitive advantage.
DXWorldEXPO LLC announced today that "IoT Now" was named media sponsor of CloudEXPO | DXWorldEXPO 2018 New York, which will take place on November 11-13, 2018 in New York City, NY. IoT Now explores the evolving opportunities and challenges facing CSPs, and it passes on some lessons learned from those who have taken the first steps in next-gen IoT services.
Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also receive...
DXWorldEXPO LLC announced today that ICOHOLDER named "Media Sponsor" of Miami Blockchain Event by FinTechEXPO. ICOHOLDER gives detailed information and help the community to invest in the trusty projects. Miami Blockchain Event by FinTechEXPO has opened its Call for Papers. The two-day event will present 20 top Blockchain experts. All speaking inquiries which covers the following information can be submitted by email to [email protected] Miami Blockchain Event by FinTechEXPOalso offers sp...
DXWordEXPO New York 2018, colocated with CloudEXPO New York 2018 will be held November 11-13, 2018, in New York City and will bring together Cloud Computing, FinTech and Blockchain, Digital Transformation, Big Data, Internet of Things, DevOps, AI, Machine Learning and WebRTC to one location.
@DevOpsSummit at Cloud Expo, taking place November 12-13 in New York City, NY, is co-located with 22nd international CloudEXPO | first international DXWorldEXPO and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The widespread success of cloud computing is driving the DevOps revolution in enterprise IT. Now as never before, development teams must communicate and collaborate in a dynamic, 24/7/365 environment. There is no time t...