Vesijama, the Very Simple Java Mail library

PDF

Here’s the story about why I wrote a mail API wrapper in Java and made it Open Source. It is called Vesijama, Very Simple Java Mail.

Vesijama has been renamed and moved to Simple Java Mail!

Prologue

So I was looking into sending some emails from my little Java webapp, right. I thought: easy, java has built in mail support called JavaMail. Well, I was in for an unpleasant surprise when I found out I was merely handed the sand grains to build my castle. I can’t just say to Java’s mailing library Hey, here’s what I want to send, and here are the addresses I need it sent to, no. I can say however I want you to formulate a mixed multipart message with the following attributes and these addresses encoded into special objects and oh yeah, define some mimemessage bodyparts for these attachments and use the following headers and put everything in a very specific nested structure dot dot dot.

You actually need to research the RFC for mail structures to do it properly! In case you’re interested (which you’re not), check out this page of useful email rfc’s. The rfc’s 822, 2047 and 2045 are referenced in Java’s MimePart alone. That’s just stupid, I can’t think of anything else where the JDK is forcing developers to work on such a low level where you need to deal with rfc’s.

An example of the JavaMail madness can be found on a thread at velocityreviews.com, where someone asks for a simple tutorial to learn how to simply send emails using JavaMail. Here’s the answer of one of the members:

First, you need to read and understand the relevant RFCs governing Internet
email, if you don’t already understand this. I’d recommend starting with:

RFC 2821 – Simple Mail Transfer (SMTP)
RFC 2822 – Format of Internet Messages
RFC 1939 – Post Office Protocol (POP3)
RFC 2060 – Internet Mail Access Protocol (IMAP)

then moving on to MIME:

RFCs 2045 – 2049 – Multipurpose Internet Mail Extensions (MIME)

Once you understand this, you should be able to figure out JavaMail using
the tutorial at http://java.sun.com/developer/onlineTraining/JavaMail/contents.html,
(which is, incidentally, the first hit returned from a Google search on the
term “javamail tutorial”), along with the JavaDoc that is shipped along
with the JavaMail libraries. If you have any specific questions about how
JavaMail is to be used, please post them to the news group and you’ll be
pretty sure to get an answer.

Cheers!

With all his good intentions, this guy doesn’t realize he’s completely scaring the mail novice away; people looking for a way to send emails shouldn’t be required to be RFC educated email engineers. I just now realize that maybe JavaMail wasn’t meant to be used by Joe sixpack, but rather by third-party library vendors. Also, realize that JavaMail is much more than just smtp client API. Still, when I began writing Vesijama there weren’t a whole lot of third-party options, let alone one as simple to use as Vesijama.

Don’t get me wrong though: it’s not that the JavaMail API is so bad, it’s great actually. It allows for very finegrained configuration for pop3, smtp and everything mail related. It’s just that you don’t want regular Java developers to deal with API on such a low level: it takes a lot of time getting it right and the risk of a faulty implementation is very high, as the result will often work in some email (web) clients and subtle mistakes with significant consequences will go unnoticed.

Enter Vesijama, the Very Simple Java Mail library

To spare other developers the same fate, I decided to write a proper wrapper around the JavaMail smtp API so no Java developer needs to be bothered by this stuff and just keep pluggin’ on an abstract business logic level. You know, just send the damn mails.

It took me quite a while to get it right since email clients, especially web clients, are very sensitive to incorrect nested structures. I’m happy to say I’ve succesfully used this when I was working for a commercial company, which means it has been professionally tested with a broad range of email (web) clients.

Enter Vesijama. It´s been a while since I wrote this little framework, I´ve only recently had the time to properly prepare the code for an Open Source release. At the time of writing the library I didn’t know about Spring’s mailing facility or Apache’s Commons Mail libraries, but in hindsight I think there’s a place for Vesijama since in my completely biased opinion it is by far the easiest to use framework. Look it up over at Vesjiama at Google Code simple-java-mail at GitHub.

Here’s the one and only code example from the Vesijama project page:

Oh wow, is that it? Well, I just imagine masses of people gazing with open mouths thinking that, but that’ll never happen because nobody realizes how much effort went in the rfc research. And the very few lines that make up the mail structure don’t look very impressive either… the thing is it has to be just right; mail clients aren’t very forgiving. It often amazes me how many thousands of lines of rfc text results in miniscule implementations, but luckily in this case at least if you do it right, it works in all email clients that properly handle emails according the rfc’s.

Anyway, the library suited me and now it’s yours too. Enjoy.

Tags:
  • javadoc

    nice. on problem i have with this is: applemail.
    as soon as you use embedded images, die displays them inline as well as attached (so doubled). any idea?

    Reply

  • Benny Bottema Post author

    Although I am not familiar with Apple mail, I have seen this behavior before. It was a ‘feature’ provided by the email client (web based) that always attached embedded images. Are you sure this is not intended behavior with Apple mail?

    Reply

    • Rich

      Hi Benny,

      Thanks for open sourcing this – it looks like a great little API. Not sure if there’s a support mailing list or forum…?

      After following the example on your googlecode page I’m having a bit of trouble embedding images. I can see them appearing as attachments, and I’m referencing them in my email html using src=”cid:xxx” however when I inspect the html that arrives in my inbox I just see an empty tag. Any ideas?

      Cheers.

      Reply

  • Benny Bottema Post author

    Hello Rich,

    There’s no mailing list or forum… yet. I may put up one in the future, if there’s enough demand.

    Regarding your issue with the embedded issue, I can take a look at your code if you would send a sample code to ‘b dot bottema at projectnibble dot org’. Also, is the problem consistent with other mail viewers?

    Reply

  • you.rock

    Cheers for this!!! Nice work.

    Reply

  • Casual Observer

    Any advantages over the Apache Commons Email library?
    http://commons.apache.org/email/

    Reply

    • Benny Bottema Post author

      I think it is easier to use!

      If you don’t mind, I’ll just put a quote here from the Vesijama wiki.

      Alternatives
      There are some alternatives around, such as the Spring mailing framework or the Apache Commons Mail. However, Spring works a bit awkward with anonymous subclasses and stuff (and you need Spring in your dependencies), while Apache Commons Mail isn’t as simple as it could be.

      Reply

  • Jordan

    It worked perfectly right away and is exactly what should have been built into JavaMail. Thanks!

    Reply

  • Frederica Segler

    Hi mate, when browsing at your blog i see some kind of weird codes all over the page, in case it’s important I just thought I’d let you know it says this with all sorts of other stuff after it: Message : Exception of type ‘System.Web.HttpUnhandledException’ was thrown.

    Reply

  • Nikhil

    Using the required jars I run the above code.. But it gives me following error.
    Exception in thread “main” org.codemonkey.vesijama.MailException: Generic error: 530 5.7.0 Must issue a STARTTLS command first. c16sm4320791rvn.13

    Can you please help me how to get out of this..

    Reply

  • Davin

    Ever thought about posting your excellent library to a maven repository? Thanks for it!

    Reply

  • canistel

    Works flawlessly for me; thanks for a very useful library.

    My one criticism of it would be the name, as I had to change the filename of the .jar… there is no way I’m installing a file on my client’s computer with a name like “vesijama” 🙂

    Reply

  • Vick

    Is this available on Maven?

    Reply

  • vib

    Will it support ICalendar events as well ? If want to send out an meeting request in text/html format .

    Reply

  • Pete

    Mr. Bottema,
    Thanks for making mail in java easier, especially for us noobs. I’ve installed the library jars and unfortunately when I try to run your code the servers – I’ve tried my google and comcast accounts – apparently refuse to connect. I’m using Eclipse and my JRE is up to date. The code I’m using is
    import javax.mail.Message.RecipientType;
    import org.codemonkey.simplejavamail.Email;
    import org.codemonkey.simplejavamail.MailException;
    import org.codemonkey.simplejavamail.Mailer;
    import org.codemonkey.simplejavamail.TransportStrategy;

    public class googleEmail {

    /**
    * @param args
    */
    public static void main(String[] args) {

    final Email email = new Email();
    email.setFromAddress(“lollypop”, “[email protected]”);
    email.setSubject(“hey”);
    email.addRecipient(“C. Cane”, “[email protected]”, RecipientType.TO);
    email.setText(“We should meet up! ;)”);
    email.setTextHTML(“We should meet up!“);

    new Mailer(“smtp.comcast.net”, 465, “[email protected]”, “password”, TransportStrategy.SMTP_SSL).sendMail(email);
    }// end of main

    }// end of class

    and the first part of the returned error is

    2011-04-15 10:37:45,777 DEBUG Mailer – starting mail session (host: smtp.comcast.net, port: 465, username: [email protected], authenticate: true, transport: SMTP_SSL)
    2011-04-15 10:37:47,386 ERROR Mailer – Could not connect to SMTP host: smtp.comcast.net, port: 465
    javax.mail.MessagingException: Could not connect to SMTP host: smtp.comcast.net, port: 465;
    nested exception is:
    java.net.ConnectException: Connection refused: connect
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638)
    at javax.mail.Service.connect(Service.java:317)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at org.codemonkey.simplejavamail.Mailer.sendMail(Mailer.java:224)
    at googleEmail.main(googleEmail.java:29)
    Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(Unknown Source)
    at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.connect(Unknown Source)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:288)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:231)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900)
    … 6 more

    I suspect it is something in a configuration but am clueless. Have you seen this type of error before and can you make any suggestions?

    Thanks,

    Pete

    Reply

    • Benny Bottema Post author

      Hello Pete,

      One thing you can do first is set mailer.setDebug(true);, which will output much more info.

      Seeing you get a connection refused and not some authentication problem or ssl handshake message, I think your connection is being blocked by either your firewall, your ISP or maybe you are behind a proxy?

      Also, have you tried the SMTP_TLS strategy to connect to Google’s smtp on port 587?

      Reply

  • Pete

    Benny,

    Thanks. SMTP_LTS did not work, but it could have been a combination of things. It seems there are number of ways to do this, and they might conflict, and with the unknowns you pointed out, I really can’t say if I’ve truly tried it. I will try this from a different network connection and see if that fixes it. If you believe the fundamental code is ok, then it probably is that.
    Thanks Again!!

    Pete

    Reply

    • Benny Bottema Post author

      Well, I took your code as example and it worked for me when I use my own gmail account to send the mail. It must be a port problem because of a firewall, ISP or proxy or something.

      Reply

  • Tom Vicker

    Hi Benny,

    I just have a few questions hopefully you can answer:

    1) I looked at the Mailer class at http://code.google.com/p/simple-java-mail/source/browse/tags/vesijama%20v1.1/src/org/codemonkey/vesijama/Mailer.java and I did not see a constructor that takes a TransportStrategy. Is that code old ? If so, can you update ?

    2) I am a bit confused between SSL and TLS. After reading SSLNOTES.txt file in the javamail-1.4.4 distribution it appears these are mutually exclusive (i.e. you can encrypt without using user, password, etc or visa versa). Do you know whether this is true ? If yes, can vesijama support it both ways ?

    3) Is your jar compatible with the recently released javamail 1.4.4 ?

    Thanks!

    Tom Vicker

    Reply

    • Benny Bottema Post author

      Hello Tom!

      1) The javadoc you reference is from the vesijama 1.1 tag, while the latest release is 1.8. It’s true I haven’t managed the tags properly, but the trunk reflects what is in the 1.8 release, which would be the following: http://code.google.com/p/simple-java-mail/source/browse/trunk/src/main/java/org/codemonkey/simplejavamail/Mailer.java. You’ll notice these constructors do accept a TransportStrategy

      2) I’m not sure I understand your question. Vesijama supports both SSL and TLS. Depending on the server implementation, both may be applicable (gMail allows both for example, on different ports), but you will need only one. Just choose one. Btw, TLS actually *is* SSL, just a later version.

      3) I have not tested this yet, but I will over the weekend (or you may report your results when you get the chance).

      Let me know if you need to know more. Meanwhile, grab the latest release here.

      Reply

  • Tom Vicker

    Thanks Benny! That was a great article about SSL and TLS and really helped me understand better. I was wondering if it was possible to send encrypted emails without requiring to authenticate to the SMTP server with user, password. Our software is distributed to 200+ clients. Their environments vary a lot and it woudn’t surprise me if one client did not need to authenticate to their SMTP server, but still desires to have their emails encrypted. If this is possible, then we would want to support that flexibility. Here is a sentence from that article you provided: “TLS allows both secure and insecure connections over the same port, whereas SSL requires a designated secure-only port.” It seems that an insecure connection over a port would mean no user/password is required, but I don’t know. If true, however, then I would think you could use TLS without providing a user and password as long as you were connecting to an insecure port. Then the Mailer class could have a constructor (I presume) that could use TransportStrategy.SMTP_TLS without needing user and password. I guess I could pass null or empty values in these fields also. Thanks again.

    Reply

  • Benny Bottema Post author

    I have just tested with JavaMail 1.4.4 and succesfully sent mails using gmail’s smtp server, using SSL and TLS.

    Reply

  • Chet

    Hello Benny,

    I tried using this tool for email….but not with much luck.
    I tried Gmail as well as my company SMTP host.

    The application is behind a firewall and I need a proxy to reach the internet. I remember seeing on the site that proxy was in the roadmap. Has it been worked out or planned.

    Let me know the way around.

    Thanks,
    Chet

    Reply

    • Benny Bottema Post author

      Hello Chet.

      In case of a firewall you can do two things:

      • Use a different port which is not closed by the firewal (provided the STMP server accepts connections on this port)
      • Configure your firewall to open the ports of your SMTP server

      In case of a proxy, you’re out of luck currently. It is on the roadmap, but unfortunately, I can’t spare my resources to implement this feature.

      Btw, Vesijama was renamed to Simple Java Mail.

      Reply

  • Ahmed

    Hi Benny,

    Is there an example using the default mailer constructor “Mailer(session)” ?

    I want to see how the session is created.

    I am getting a null pointer using it:
    [A] java.lang.NullPointerException
    [A] at org.codemonkey.simplejavamail.Mailer.logSession(Mailer.java:255)
    [A] at org.codemonkey.simplejavamail.Mailer.sendMail(Mailer.java:233)

    Thanks,

    Reply

    • Benny Bottema Post author

      Can you show me how you created the Session? You should never get a NullPointerException to begin with, but a graceful message telling you you miss an argument or property. I want to fix that anyway.

      To answer your question, a Session object is the conventional standard way of creating a mail session with JavaMail. You can find numerous examples on the internet on how to send mails using JavaMail which surely includes configuring a Session object. In Simple Java Mail it was added for compatibility reasons: you can use your old Session objects with this library as well.

      Reply

    • Rodrigo

      I am getting the exact same problem. I submitted an issue explaining the problem in the Google Code project:
      http://code.google.com/p/simple-java-mail/issues/detail?id=7

      Reply

Leave a Reply