Okay All,
I have worked quite a lot on this issue, and will try to explain what my
current findings are, so that anyone else trying to get JavaMail working
can avoid the pitfalls. I have tested several versions (snapshots, and
an M5 release candidate) and can only conclude that JavaMail API support
isn't complete yet. If it were complete, you would be able to do the
following:
In your geronimo-application.xml deployment plan add a dependency to the
Geronimo Mail component:
<dependency>
<uri>geronimo/jars/geronimo-mail-1.0-M5.jar</uri>
</dependency>
And Configure two GBeans:
<gbean name="JavaMailProtocol.smtp"
class="org.apache.geronimo.mail.SMTPTransportGBean">
<attribute name="host">192.168.10.10</attribute>
</gbean>
<gbean name="mail/MailSession"
class="org.apache.geronimo.mail.MailGBean">
<attribute name="transportProtocol">smtp</attribute>
<attribute name="useDefault">false</attribute>
<attribute name="debug">true</attribute>
<reference
name="Protocols"><name>JavaMailProtocol.smtp</name></reference>
</gbean>
Then in a Stateless Session Bean's Object JavaDocs you can put this
XDoclet tag:
* @ejb.resource-ref description="JavaMail Resource"
* res-ref-name="mail/MailSession"
* res-type="javax.mail.Session" res-auth="Container"
* res-sharing-scope="Shareable"
Or, if you're still using Deployment Descriptors directly, something
like the following in your ejb-jar.xml would work:
<resource-ref >
<description><![CDATA[JavaMail Resource]]></description>
<res-ref-name>mail/MailSession</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Okay, so why in the world doesn't this work? Well, there's no actual
providers available in Geronimo to support the SMTP protocol. So, what
you end up with is an execption that looks like this:
javax.mail.NoSuchProviderException: Unable to locate provider for
protocol: smtp
at javax.mail.Session.getProvider(Session.java:225)
at javax.mail.Session.getTransport(Session.java:331)
at javax.mail.Session.getTransport(Session.java:320)
What's nice is the Geronimo developers have gone through and implemented
the javax.mail.Session class and if there were some providers available
it would be possible to tell Geronimo's Mail API about them and have
them used. I've confirmed that it would get that far, if there were any.
So, why not use the JavaMail reference implementation from Sun? You
could personally do so, yes, download it, put its jars into the Geronimo
repository and you'd be able to do just that. Personally I downloaded
the JavaMail mail.jar and JAF activation.jar and put them into
repository/javamail/jars/ under my Geronimo server root. Then I added
the following dependencies before the geronimo-mail dependency in my
geronimo-application.xml deployment plan like so:
<dependency>
<uri>javamail/jars/mail.jar</uri>
</dependency>
<dependency>
<uri>javamail/jars/activation.jar</uri>
</dependency>
<dependency>
<uri>geronimo/jars/geronimo-mail-1.0-M5.jar</uri>
</dependency>
Now, when I write code like the following in my SLSB bean, it gives me a
Session and I can use it to get a transport and send mail:
InitialContext ctx = null;
try {
ctx = new InitialContext();
javax.mail.Session session =
(Session)ctx.lookup("java:comp/env/mail/MailSession");
MimeMessage mes = new MimeMessage(session);
mes.setFrom(InternetAddress.parse("[EMAIL PROTECTED]")[0]);
mes.setRecipients(RecipientType.TO,"[EMAIL PROTECTED]");
mes.setSubject("Testing");
mes.setSentDate(new Date());
mes.setContent(body,"text/plain");
mes.saveChanges();
Transport transport = session.getTransport();
transport.connect();
transport.sendMessage(mes,InternetAddress.parse("[EMAIL PROTECTED]"));
transport.close();
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
if (ctx != null) ctx.close();
}
This looks easy enough. But there are problems with this. What's
actually happening behind the scenes here is that the $getResource()
method of the MailGBean is being called to obtain a javax.mail.Session
instance. MailGBean makes a fairly fatal mistake in how it sets up the
Session's default Properties, however. Sun's JavaMail will not accept
any properties that aren't Strings when it goes to parse things. So
although you can see that I set the attribute 'debug' to 'true' in the
MailGBean configuration, above, it is actually converted to a Boolean
object, and that object is put into the properties. And Sun's JavaMail
ignores it because it's not a String.
So that means that although it's nice to have the MailGBean and
associated ProtocolGBean subclasses, the way they build the Properties
for the Session isn't compatible with Sun's JavaMail implementation, so
you can't use it.
So that leaves me with no alternative, at this time, than to add the
JavaMail dependencies, and use Sun's JavaMail API directly to obtain
sessions through the javax.mail.Session.getDefaultInstance() method
instead of the more typical resource-ref and InitialContext.lookup().
As I say, this is how it is with the current state of Geronimo, days
before an M5 release. I'm just reporting... I know it'll get fixed up
soon anyway.
Cheers.
-Neal