First let’s explore the main objects that we are concerned with for simple interfacing of a Java application with a Gmail account using the Javamail API. The Session object is the main object holds the connection configuration information and factory methods for itself and the other two main objects, Transport and Store. Almost all configuration information needed for connecting to, authenticating with, and sending and receiving email can be handed to the Session object’s Session.getInstance(Properties props) factory method via the Java Properties object argument, but at least in this case, we are not going to hand anything into the Session, so we can see where the info is coming from as we step through the code (Yes, there is code coming eventually!). The Session is not really a session like an active connection, just the holder for the settings and the factory methods for the Transport and Store objects.
Transport and Store represent send and receive capabilities respectively. This didn’t make a whole lot of sense to me at first, but I realized that the two capabilities speak to two different hosts with two different protocols. Also, I would think that the send capability is used most often by developed applications (sending mass emails, email alerts, confirmation emails, etc.) so there is typically no need to have both capabilities simultaneously.
To get a Transport, we call the factory method on our Session object, session.getTransport(). This is where things can get confusing since there are several ways to configure the connection. This factory method will take no arguments (which will get all its configuration from the configuration stored in the Session object), an Address object (which will apparently provide a place to load the Transport object with the information it needs to configure itself), a Provider object (which will configure the returned Store object), a URLName object (not really sure the use of this one), or a String designating the protocol.
To get a Store, we call the factory method on our Session object, session.getStore(). This is the same place things can get confusing for the same reason as the Transport factory method. This factory method will take no arguments (which will get its configuration from the configuration stored in the Session object), a Provider object (which will configure the returned Store object), a URLName object (not really sure the use of this one), or a String designating the protocol.
For simplicity’s sake in my example code, I did not hand the Session object ANY configuration via its factory method with the Java Properties object argument so that we can see and know for sure where the configuration info comes from. For Gmail specifically, for both the Transport and the Store, I used the respective factory methods that take the String for the protocol. For Gmail, send is “smtps”, receive in my case is “imaps.” Gmail allows POP3 as well, but I liked IMAP better since there were more methods on the Message object that were supported by IMAP (for example getReceivedDate()). The “s” on the end of the otherwise familiar protocols is for SSL.
Now! After all this, we need to actually connect to the Transport and Store. Both objects have the same connect methods that take similar arguments. This is another point of confusion, since the method will take usernames and passwords along with the host name. This is where I passed this information in instead of passing it into the Session object via a Java Properties object. I think this is better for learning since we know where all the values are coming from at development time.
As the code matures, things could be progressively moved to a “higher” configuration level so that all configuration efforts could be focused in one place. Every value used directly in the code (protocols, host names, usernames, and passwords) could be read in from a properties file using a Properties object and handed into the Session factory method enabling us to use the no-argument Transport and Store factory methods on the Session and the no-argument connect() methods on the Transport and Store. However, I think for demonstration purposes, this makes it easier to understand. You can figure out your own best way to do things, there are several choices with the JavaMail API.