Amazon AWS SDK's AWSJavaMailTransport screws up Play's Mail Abilities

293 views
Skip to first unread message

Riyad

unread,
Jan 28, 2011, 8:15:41 PM1/28/11
to play-framework
Been trying to debug a failing Play Mailer on localhost (postfix, no
security) for the last 2 hours until something in the debug log
finally clicked in my brain:

-----------
DEBUG: getProvider() returning
javax.mail.Provider[TRANSPORT,aws,com.amazonaws.services.simpleemail.AWSJavaMailTransport,Amazon
Web Services LLC]
-----------

this particular project includes the entire Amazon Java SDK (it only
comes as a single bundle - aws-java-sdk-1.1.4.jar) and it seems
somewhere inside of that SDK it provides a JavaMail transport (of type
'aws' according to this
http://docs.amazonwebservices.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleemail/AWSJavaMailTransport.html)
that for some unholy reason JavaMail keeps picking when I try and send
a standard email over SMTP.

I've tried "mail.transport.protocol=smtp" in the application.conf but
JavaMail still insists on picking that transport.

A quick workaround would be to repackage the Amazon SDK yourself, but
I'd like something more elegant and I haven't found it yet.

If anyone has any ideas, the help would be appreciated, but more
importantly I posted this so Googler's at least have a hit if they
search for "Play" "JavaMail" "localhost" "smtp" or something along
those lines and get a hint at what's wrong.

Riyad

unread,
Jan 28, 2011, 8:32:15 PM1/28/11
to play-framework
Upon further investigation, it looks like aws-java-sdk-1.1.4.jar/META-
INF/javamail.default.providers file doesn't *compliment* the one
provided in the javamail.jar file, it totally replaces it, so JavaMail
thinks there is only 1 Transport available in the system and returns
it -- Amazon's Simple Email Service transport.

I have a feeling a quick fix for this might be to move the Amazon SDK
to the Play installation's /framework/lib dir so it loads on boot (and
hopefully before javamail.jar does) instead of after javamail.jar as
part of the webapp's dependencies.

This is such an ugly problem... if anyone else has suggestions I'd
love to hear them.

On Jan 28, 6:15 pm, Riyad <rka...@gmail.com> wrote:
> Been trying to debug a failing Play Mailer on localhost (postfix, no
> security) for the last 2 hours until something in the debug log
> finally clicked in my brain:
>
> -----------
> DEBUG: getProvider() returning
> javax.mail.Provider[TRANSPORT,aws,com.amazonaws.services.simpleemail.AWSJav aMailTransport,Amazon
> Web Services LLC]
> -----------
>
> this particular project includes the entire Amazon Java SDK (it only
> comes as a single bundle - aws-java-sdk-1.1.4.jar) and it seems
> somewhere inside of that SDK it provides a JavaMail transport (of type
> 'aws' according to thishttp://docs.amazonwebservices.com/AWSJavaSDK/latest/javadoc/com/amazo...)

Riyad

unread,
Jan 28, 2011, 8:36:25 PM1/28/11
to play-framework
correction: The file in the AWS SDK is called "javamail.providers",
not "javamail.default.providers"

so I'm not entirely sure why JavaMail isn't gracefully adding the AWS
transport.

Riyad

unread,
Jan 28, 2011, 9:11:00 PM1/28/11
to play-framework
Just an update for anyone else wanting a conclusion -- I haven't tried
JavaMail 1.4.4 yet (1.4.3 comes with Play! 1.1) to see if it fixes the
issue, I just went ahead and removed the javamail.providers file from
the Amazon AWS SDK and viola, everything started working just fine.

In hindsight this looks like a JavaMail bug in how it's scanning the
classpath for properties files and consuming them -- the protocol
defined in the AWS file is "aws" so it's inclusion into what I can
only imagine is a protocol Map managed by JavaMail shouldn't have any
collisions with "smtp" -- so it seems the presence of that file was
causing JavaMail to just not load it's own defaults or something
equally as frustrating... I'm not entirely sure.

For anyone more curious about those META-INF property files, here is a
link with more bits about them:
http://java.sun.com/products/javamail/javadocs/javax/mail/Session.html

I suppose something else I could have tried would be to define a META-
INF dir in my own classpath and populate it with a custom
javamail.providers file that contains all the providers between the
JavaMail and AWS SDK JARs and see if that would fix it.

But again, I'm exhausted by this issue and just went the easy route.

Riyad

unread,
Jan 29, 2011, 9:49:06 AM1/29/11
to play-framework
I spent more time on this issue this morning and wrote up everything
here:
http://www.thebuzzmedia.com/javamail-smtp-on-localhost-fails-with-amazon-aws-sdk-in-classpath/

The short of it is that regardless of classpath manipulation, JAR
location or javamail.providers / javamail.default.providers location,
I cannot get JavaMail to load it's default provider list when another
JAR on the classpath contains a javamail.providers file -- which is
the *defined* way for your classes to load additional providers into
JavaMail.

(I have also tried JavaMail 1.4.4)

I am following up with the AWS folks to see if they can help. I keep
insisting on updating this thread because it is the type of issue that
stops you dead in your tracks and if you are getting no hits on Google
with it, you want to pull your pancreas out through your ears in
frustration.

Riyad

unread,
Jan 29, 2011, 10:59:50 AM1/29/11
to play-framework
PROBLEM SOLVED: http://www.thebuzzmedia.com/javamail-smtp-on-localhost-fails-with-amazon-aws-sdk-in-classpath/#solved

It turned out to be the Amazon-provided "javamail.address.map" file in
the AWS SDK JAR (META-INF directory). The file is used to bind specs
to protocols, the default SMTP binding in Javamail is:
rfc822=smtp

and that causes the default sun-created SMTP transport to load when
SMTP is used. Unfortunately Amazon rebinds this to their AWS transport
with this single entry in their own address map file:
rfc822=aws

so now when you ask for "SMTP" and the AWS SDK is anywhere in your
classpath, the AWS Simple Email Service transport is handed back to
you.

FIX: Remove the javamail.address.map file from the AWS SDK JAR file.

You can still use the AWS transport, you just have to ask for it by
name with 'aws'.

On Jan 29, 7:49 am, Riyad <rka...@gmail.com> wrote:
> I spent more time on this issue this morning and wrote up everything
> here:http://www.thebuzzmedia.com/javamail-smtp-on-localhost-fails-with-ama...
Reply all
Reply to author
Forward
0 new messages