Using JavaMail in JBoss

Michel de Groot <michel.anke@wolmail.nl>

Introduction

JBoss has a built-in implementation of the JavaMail API. You can use this service from inside and outside EJBs. We describe here how to use the service.

Installation & Configuration

  1. Edit conf/<yourconfig>/jboss.jcml and find Mail Service MBean (almost on the bottom).

    a) Replace the User and Password attributes values with the user name and password used to connect to your mail server. You can find these values in your mail program. The mail service will use this account to send mails, so be sure that this mail account works properly (test it with your mail program for example).

    b) Replace the ConfigurationFile attribute value with the file containing the mail settings. Default is "mail.properties", which is also in the conf/<yourconfig> directory. This file will be edited in step 2.

    c) Replace the JNDIName attribute value with the JNDI name for your mail session. The default is "Mail". This JNDI name will be used in jboss.xml to identify the resource. This is explained in more detail in step 4.

  2. Edit the mail properties file you identified in step 1b. By default, this is conf/<yourconfig>/mail.properties.

    Edit the following lines:

     
         mail.user = sa005697    // the user to connect with; same as in step 1a
         mail.pop3.host = pop3.wolmail.nl        // the pop host to store the mail 
    on
         mail.smtp.host = smtp.wolmail.nl        // the smtp host to send the mail 
    to 
         mail.from = Memoirs@gamesphere.com      // the 'from' field that is 
    filled in by default in e-mails
         

    You can find most value in your mail program. You might want to inspect the JavaMail specification for more details.

    The last line, mail.debug, should be set to 'true' for now. This will provide you with verbose debugging information. Once you have everything running correctly, you can set it to false.

  3. Edit the ejb-jar.xml of the EJB that uses the mail service. In your EJB, specify a <resource-ref> like this:

         <ejb-jar>
                 <enterprise-beans>
                         <session> 
                                 <ejb-name>Mailer</ejb-name> 
                                 <home>some.package.MailerHome</home> 
                                 <remote>some.package.Mailer</remote> 
                                 <ejb-class>some.package.MailerEJB</ejb-class> 
                                 <session-type>Stateless</session-type> 
                                 <transaction-type>Container</transaction-type> 
    
                                 <resource-ref>
                                         <res-ref-name>mail/MyMail</res-ref-name> 
                                         <res-type>javax.mail.Session</res-type> 
                                         <res-auth>Container</res-auth> 
                                 </resource-ref> 
    
                         </session>
                 </enterprise-beans> 
         </ejb-jar>
         

    This will tell the EJB container that the EJB uses a javax.mail.Session resource named mail/MyMail and that authorization is container managed.

    You can change the name if you like, but be sure to use the same name in step 6, in the code example.

  4. Edit the jboss.xml of the EJB that uses the mail service. If you don't have this file, create it and place it in the same directory as the ejb-jar.xml of the EJB. This file is JBoss specific and tells JBoss how to map the mail resource to the mail service provider in JBoss. In this file, specify a <resource-manager> like this:

      
         <jboss>
                 <resource-managers>
                         <resource-manager>
                                 <res-name>mail/MyMail</res-name> 
                                 <res-jndi-name>Mail</res-jndi-name> 
                         </resource-manager> 
                 </resource-managers> 
         </jboss>
         

    The name that you specify here is the name that you specified in step 3. The JNDI name that you specify here is the name that you specified in step 1c.

  5. Edit the bin/run.bat file of your JBoss installation. Include ../lib/ext/mail.jar and ../lib/ext/activation.jar in the classpath explicitly. This assumes that you start JBoss from the bin directory. If not, you should modify the paths to the jars accordingly. Make sure you list mail.jar before activation.jar or you may get cryptic errors like 'no object DCH for MIME type text/plain'.

    TO BE IMPROVED: This step should not be required; both mail.jar and activation.jar are correctly found during the ClassPathExtension scan, but somehow their classes cannot be found later. Maybe something missing in the manifest.mf files?

  6. Code example This code example assumes that you are working from inside a JBoss container. For example, this is the case if the code is placed in a JBoss managed SessionBean.

    TO BE IMPROVED: This code example does not use PortableRemoteObject, because I could not locate it anywhere in the JBoss jars. The code will work without it on JBoss. It should be used however to make the code more portable. I'm also not sure what happens in a distributed JBoss installation.

     
         import java.util.Date;
         import javax.ejb.SessionBean;
         import javax.naming.InitialContext;
         import javax.mail.Session;
         import javax.mail.internet.MimeMessage;
         import javax.mail.internet.InternetAddress;
         import javax.mail.Transport;
         import javax.mail.Address;
         import javax.mail.Message;
         //import javax.rmi.PortableRemoteObject;
    
         public class SomeEJB implements SessionBean {
                 public void ejbCreate() {}
                 
                 public void ejbPostCreate() {}
    
                 public void sendMails() throws java.rmi.RemoteException {
                         Session session = null;
                         try {
                                 session = (Session)new 
    InitialContext().lookup("java:comp/env/mail/MyMail");
                                 //session = (Session)PortableRemoteObject.narrow(
                                 //      new 
    InitialContext().lookup("java:comp/env/mail/MyMail"), Session.class);
                         } catch (javax.naming.NamingException e) {
                                 e.printStackTrace();
                         }
                                 
                         try {
                                 MimeMessage m = new MimeMessage(session);
                                 m.setFrom();
                                 Address[] to = new InternetAddress[] {new
                                 
    InternetAddress("<your_email_adres@<your_provider>.<your_extension>");
                                 m.setRecipients(Message.RecipientType.TO, to);
                                 m.setSubject("JavaMail Test");
                                 m.setSentDate(new Date());
                                 m.setContent("Test from inside EJB Using JBoss", 
    "text/plain");
                                 Transport.send(m);
                         } catch (javax.mail.MessagingException e) {
                                 e.printStackTrace();
                         }               
                 }
    
                 public void ejbActivate() {}
                 public void ejbPassivate() {}
                 public void ejbRemove() {}
                 public void setSessionContext(javax.ejb.SessionContext ec) {}
         }
       
  7. Using the JavaMail service with mail servers that require POP authentication before SMTP You can do this by using:

     
                 import javax.mail.Store;
    
                 Store s = session.getStore();
                 s.connect(); // POP authentication
                 Transport.send(m);