Design Notes

These notes comprise some thoughts I have taken the time to write down that apply to the software developed to respond to email from within the J2EE container. While by no means complete, the items in here are considered tricky enough to understand that even I wanted to keep notes.


As outlined in the specification, the EmailManagedConnectionFactory class is the starting point for access to the email system for the connection management architecture. Prior to the new J2EE 1.5 specification being implemented, there is no management of life-cycle for connectors, so this class also cheats and spawns a thread to monitor pop3 (and possibly other) servers for new mail.

When the application server calls the EmailManagedConnectionFactory.createConnectionFactory() method, an EmailConnectionFactory object is returned (the interface just specifies that it returns Object). That EmailConnectionFactory does not retain a reference to the EmailManagedConnectionFactory that created it. Instead it creates a new one each time it's needed (from the retained configuration parameters). It is this act of rehydration that causes the background thread to be started (if the BackgroundThread configuration property is true). You might note that the setBackgroundThread() property is set last so that the full configuration is available when that property 'goes live'.

This ConnectionFactory is stored in the JNDI namespace. The application calls getConnection(). The rehydrated EmailManagedConnectionFactory is passed in to the ConnectionManager.allocateConnection() method to handle "various quality of service" as required by the spec. The ConnectionManager in turn calls the EmailManagedConnectionFactory .createManagedConnection() method which creates an EmailManagedConnection.

Now, ostensibly, these managed connections could be created fresh each time based on the configuration and connection data. However, there is a problem in that multiple javax.mail Sources pointing at the same pop3 server fight with each other (my pop server says the account is locked or busy or something like that). So we have to detect when the Source for the connection would be the same as an existing one, and instead share the javax.mail Source. Hence we introduce the EmailSource object.

It holds a unique source and possibly the thread running in the background for that source. It also holds a reference to the EmailManagedConnectionFactory and EmailConfigurationData. This is not redundant even though an EmailManagedConnectionFactory is an EmailConfigurationData, since the 'connection data' part of the EmailConfigurationData may be overridden when the application calls EmailConnectionFactory.getConnection(ConnectionSpec spec) since an EmailConfigurationData object is (must be) the passed spec argument (to override). It can't hold the javax.mail Transport object too though, since different transport configurations could be associated with the same source configuration (unlikely, but a possibility). It holds a javax.mail Session though. This is required since usernames and passwords are passed in the Authenticator when the Session is instantiated. These are supposedly overridden by using the full URL when creating the Transport and Store, but there is no guarantee that the rembered Authenticator won't be used to supply those values. So there are two javax.mail Sessions one is only used for creating the Store and one that's used for creating the Transport (for sending email).

An EmailConnection and the underlying EmailManagedConnection find the EmailSource by doing a sequential search through the list, the same way an EmailSource is found for the current thread for background processing. Two static methods on the EmailManagedConnectionFactory are provided for this access. This isn't expected to be a very common operation, since receiving email is less common than sending and the EmailSource is cached by the EmailManagedConnection.

So far sources are never removed from this static list otherwise we would have to be doing reference counting, which I hate (let the COM guys do that sort of waste of time). There shouldn't be more than a few dozen distinct Store configurations, and if it's a problem I'll deal with it later.