JBoss Mail Server 1.0 Milestone 2 Release Candidate 1 has been released. JBoss Mail Server is a pure Java mail server based on the JBoss Microkernel and various JBoss Application Server Components.


Presently the M2 (RC1) release features:

  • SMTP Server - to send mail
  • POP Server - to retrieve mail
  • TLS Support for POP and SMTP - to secure your transport
  • SSL Support for POP and SMTP - not all mail clients support TLS
  • JMS Integration - mails can be processed by message driven beans
  • Extensibility though JMX configuration and custom Mail Listeners
  • Database-based mail storage
  • Graphical installation
  • And more


While this is an early milestone release, JBoss Mail Server is already used by some as their mail server and is already being put to commercial application. JBoss Mail Server seeks to provide a complete mail solution for both tier-1 mail services presently supported by traditional mail servers such as Sendmail and Postfix as well as tier-2 mail services presently provided by Microsoft Exchange and Lotus Domino. The roadmap for future releases of JBoss Mail Server is emerging and can be located here.


One of the new features of this release is a (still rather rough) graphical installation. To install JBMS, install the Java Development Kit, JBoss Application Server, and grab the JBMS binary from here. Unzip the binary and run the "install.sh" or "install.bat" script (there are also instructions in the included INSTALL.txt). A splash screen will go by and next you'll see the first dialog prompting you for basic configuration information:



If you happened to predefine JBOSS_HOME then the installer will pick it up. The configuration name determines which directory under $JBOSS_HOME/server to find the "deploy" directory. If you run JBoss with the normal "run.sh" or "run.bat" command and no arguments then the answer is "default". If you run it with a "-c bla" then the answer would be bla. Select which mail services you want. A basic mail server consists of SMTP and POP. POPSSL will give you a separate POP instance listening on a separate port encrypted with SSL. Be sure and set your hostname appropriately and even more importantly -- set the domain. The domain is usually what shows up after the @ symbol in your email address. Once you are satisfied click next and you will see this screen:



If you selected less than the default 3 services then your screen may appear slightly differently. A general use mail server should have True, False, True, False. Enabling TLS allows mail clients that support encryption via TLS to connect to the server this way. If you require TLS for SMTP then outside servers will not send you mail. TLS support for POP is a good idea but not all mail clients support it (more often they support dedicated POPSSL) so requiring it may not be such a hot idea. Once you click next you will see:



Your screen may look different depending on what services you have selected. The default port assignments are generally the correct ones. Changing the SMTP port will likely make it impossible for other SMTP servers to locate your server. If you change any of the ports then users will have to be informed because their mail client will suggest these defaults. That being said many UNIX operating systems require you to run JBoss as root if it is to use ports < 1000. Therefore you can set them to higher ports and use iptables to forward the port. Do whatever you feel comfortable with and click next.



If you know what DNS servers you wish to use you can enter them here. If you do not enter any, then JBMS will use whatever your default route is. You can discover your DNS servers either by looking at your network configuration or on most UNIX variants and on Windows XP you can try the nslookup command which usually reveals the IPs of your DNS servers.



For my systems, which are all UNIX-based (Linux, Mac OS X), I just use the default route and hit next.



If you have configured (or plan to configure) another database for your JBoss instance, then you can select it here (so long as you plan to use MySQL) otherwise select other and JBMS will default to Hypersonic mappings. If you need help configuring another database by hand or want to help us add/test defaults for another database to the installation tool then ask on the forum. Mapping is done through the "jbosscmp-jdbc.xml" file which will be located in $JBOSS_HOME/server/$JBOSS_CONFIG/deploy/mail.ear/entitymailbox.jar/META-INF and though JBossMQ's configuration. You can get the appropriate JBossMQ configuration for your database from $JBOSS_HOME/docs/jms and find instructions here. We are interested in making this part automatic for everyone so please give us feedback in the forum. Clicking next brings us to the keystore configuration if you have any TLS or SSL based services (if not skip the next two sections since the installer will):



If you have an existing keystore you can configure it here. If not we can generate one for you. Be sure to enter a password that is at least 6 characters long if you are generating the keystore. We pre-populate the path to the keystore for you. the ${jboss.server.home.dir} alias points to $JBOSS_HOME/server/$JBOSS_CONFIG directory. You can replace this with an absolute path if you wish. If you choose to generate the keystore you'll be brought to another screen configuring it (if not then skip this section):



You must enter the absolute path (even if you used the ${jboss.server.home.dir} alias previously) as the key generation tool is not smart enough to unalias it. You do not have to answer the questions on this screen correctly. You can put whatever you like. Do note that this will create a self-signed key which most clients will warn the users about. If you do not want that then go order a professionally signed key from these nice people. Click next and we'll set up some users:



Here you can add some user/password combos for mail accounts. You can have more than 5 in JBoss Mail Server, but you'll have to configure those yourself (edit $JBOSS_HOME/server/$JBOSS_CONFIG/deploy/mail.ear/mail.sar/META-INF/jboss-service.xml). Once you've added a few users click next.


The installer will install JBMS into your JBoss Application Server instance. You can start JBoss by going to the directory to which you installed it and typing either "bin/run.sh" or "cd bin {enter} run.bat". However, if you had happened to have JBAS running in advance, the installer would have hot deployed JBMS anyhow (see how cool we are)! The messages that JBoss reports should look like this:



Now we can test it! I use Mozilla Thunderbird as my mail client. If you use another mail client, that's okay, but the screenshots below are from Thunderbird. Your mail client will most likely use similar terminology. When I open Thunderbird, I get a menubar at the top of the screen. I select Tools->Account settings:



A screen like like this pops up:



I click add account and am taken to the account wizard:



Obviously I want an "Email account".



If this were a real external facing mail server it would say something like president@whitehouse.gov rather than andy@powerbook.localdomain. Anyhow, these settings are just fine so I press next:



I select POP (IMAP is still a few milestone releases away) and choose "powerbook.localdomain" as my mail server (just like what I configured in the installation). I uncheck global mail store since I want these test mails separate from my work emails.



Andy is indeed my username.



This is just a description for the overall account that will appear as the category in the left hand tree on the main screen for your inbox, sent, trash. The email address makes a fine label, so I click next.



How nice! Thunderbird has congratulated me on this amazing feat! However, I am not quite done since it has chosen my default SMTP server for outgoing mail rather then powerbook.localdomain! Let us fix that by clicking okay and going to the Tools->Account settings and navigating to andy@powerbook.localdomain (or whatever you set).



On OS X for some reason it does not really like connecting by name so I change the server to "" (this wouldn't be a problem for a real server, but I am running locally on my laptop). I also make sure that "Use Secure Connection (SSL)" is selected. Thunderbird doesn't appear to support TLS, so I use my POPSSL instance. Now lets select "Outgoing Server (SMTP)".



We see my default SMTP server. Lets add one. Click advanced.



We should just see the default SMTP server, click Add.



We'll specify the IP as the server name (name is okay normally but OS X doesn't seem to like "powerbook.localdomain" or even localhost even though I have /etc/hosts configured and lookupd configured to use /etc/hosts). I am going to specify that I must pass a username and password and that I want TLS support. Thunderbird does support TLS for SMTP and its wise to use it. You don't want to pass your mails and password over the broad internet in the cleartext do you? Okay not a problem if we are going to localhost but the point is to lecture you on the sense of using SSL/TLS! I click OK and go back to my server settings:



I want to use a different SMTP server than my default so I click Advanced and click the SMTP tab.



Now let us create a test message:



Make sure your From: is set to your new mail server. Also consider turning off HTML mail in your settings, it annoys most internet users and only spammers find it exceptionally useful! Send the mail to yourself so that we cant test POP!



WHOA! Our mail client does not trust our new mail server! Okay, its just complaining that we do not have a certificate authority singing our certificate, we signed it ourself. Accept the certificate and click okay.



You may not see the above screen. It is mostly because I put my IP as the server name rather than the hostname. Just click okay if you do see this.



You will now be asked for a password. You do remember what you put as your password during the install right? Enter it and click OK. It will send the mail. Now lets click "get mail" for this account from the top menu bar. You will get more SSL warnings (click okay) and then:



Excellent! As you can tell I send myself lots of mails. Some of them I even spell correctly! Anyhow, if you have trouble with your general mail server setup consult the JBoss Wiki or ask in the forum. We hope to get more feedback and discover any major bugs in the next few day otherwise M2-RC1 becomes M2-Final. So please let us know if something seems broken.


This release is not a "performance release" its a feature and stability release. There is some great performance work being done in the HEAD of CVS and in the special branch called "Nokia_Branch_1" (this should be more stable but lacks some of the work on the installation). For those of you who are geekier, the install tool is basically ant with some custom tag libs. If you're interested in it you can check out the module in CVS called "cheese". Remember, JBoss Mail Server M2 RC1 is guaranteed or your money back! :-)


Rule #2 - Use direct JDBC for persistence (remember this is how to do it the WRONG way)


By using JDBC directly, you increase the complexity of YOUR code or reduce its scale. You are forced to implement your own data paging, own transaction handling, and own cache strategy (but not necessarily your own cache). You are also likely to increase the weight on the garbage collector thereby reducing performance.

In the event that you handle techniques like paging the data that you load, you opt for more complexity (which is a corollary to increased entropy and bugs). In the event that you do the simple minded thing "select * from table where bla=?" then you increase the amount of memory utilization and risk forcing more frequent full garbage collections.


It is still possible to utilize caching via JBoss Cache or similar products, but you will likely have to implement the "strategy" yourself. If you do not do this, and just query the database, then you increase the load on the server because you must reload data for every request for every user (don't forget the garbage collector!). If you do opt to implement your own cache strategy (when to put, when to get) then you will increase the complexity of your code. The worst thing you could do is use the HTTP Session as a Cache.


It is still possible to use a transaction manager with direct-JDBC but you will have to write your own transaction handling. Meaning, you will have to decide when and if you want a transaction. This increases the complexity of your code while reducing its reusability. We'll talk more about this next time.


Note that DAOs and other said patterns reduce the coupling of this code, they do not address the problem itself. You still have to implement it and you still have the added complexity as a result.


Inverse - Use a automated persistence (such as Hibernate)


Using a persistence mechanism such as Hibernate or even CMP, you can take advantage of both eager and lazy loading thus paging the data appropriately. Furthermore, you can utilize second-level cache, thus reducing load from IO and garbage collection. Lastly, you can utilize managed transactions. What's more is that you get all of this for free. Again, do you want to own that (I've read that O-R mapping is as high as 60-80% of most modern business apps)? Let JBoss help!


Next up: How not to handle transactions. Previously: using the HTTPSession as a Cache


I was writing this really long entry on the messed up things people do in their J2EE applications, but I lost my own attention due to the length. I figured I would break it up. This series will focus on how to make your application run poorly on JBoss and then give the inverse as well. Most of it will be just generic computer science type stuff, but it will all be with a JBoss-twist. My interest is performance and scalability not things like J2EE compliance. I will try and note where compliance might be an issue, but it is not possible to produce a completely scalable drag-and-drop application. This is going to focus on the idea that you are developing for a cluster of 1 to many JBoss instances. It hardly matters what you do for extremely small applications with limited requirements -- or does it?


Rule #1 - Use the HTTP Session as a Cache for database data (remember this is to SCREW UP your application)


By using the HTTP Session as a cache you can maximize the serialization your application does thereby limiting your scale and performance. Yes it works great on one system but when you have a cluster, the data must be serialized across all of the nodes every time you call "setAttribute()". Furthermore, the more nodes you have in the cluster, the more time they spend processing state replication messages (passed over multicast via JGroups).


As an added bonus, it is much easier to blow the JVM's heap size (OutOfMemoryException). It is likely that you do not know how big that session is getting, nor the objects created as overhead to replicate it across the cluster. Nor do you know in advance how many users will login at peak. Thus this is a recipie for "fall off the side of a cliff" degredation even if you do not blow the heap.


Inverse - Use second-level cache in your persistence mechanism and keep the Session as small as possible


Whether you are using EJB CMP, Hibernate or JBoss Cache directly -- you have access to a second-level cache in JBoss. Generally, if you could cache the data in the session, you can cache the data in second-level cache. Moreover, the data does not have to be replicated.


Both JBoss CMP and Hibernate offer "cache invalidation" and LRU algorithms to size this data appropriately. Meaning, you can use one persistence configuration to write the data which will send an invalidation message to the nodes whenever the data changes and invalidate it from cache. The data is not replicated to each node. In the event of a failure, you would just have a cache miss. This offers probably cleaner data than you could achieve in the HTTP Session.


Moreover, Hibernate offers optimistic locking strategies and dirty checking. It can merely check the data's staleness if it was used in a write rather than use cache invalidation (which could still be a little overwhelming).


JBoss CMP offers "Commit Option D" allowing the data to be flushed at regular intervals. This may be good enough in many cases and may have less overhead than cache invalidation for some datasets.


Rolling your own - Writing a persistence mechanism is easy, doing it right...


O-R mapping and caching are nothing new and are not hard to write. Writing them correctly so that they can be highly concurrent and writing advanced features such as cache invalidation is somewhat harder. Its not code you want to own or maintain and your boss is not likely to want to pay you to write and support it. JBoss can help you with solid and well-used, tested implementations. Its likely that the #1 most used appserver, JBoss, will have a better general use implementation then you could write as part of your development cycle while you write your business application. Moreover, if it does not completely suit your needs, you can use it as a baseline and have your changes committed to the appserver codebase. This can substantially lower your cost of ownership of your overall codebase. If caching is not part of your core business, then why focus on it as part of your day job. Let us help!


Next up: How not to do persistence

Filter Blog

By date: