Email application Using JNDI with Tomcat and Unit Test

Email application Using JNDI with Tomcat and Unit Test

 

Using JNDI in a tomcat environment came to my job recently. It was not that bad to use it but how to do the unit test before you deploy it onto tomcat was really annoying part. I wish the following article could help you to work out as how I have tried. I will go through an email application to show you how these three parts works together.

 

Let’s first look at the source code for handling email.

 

public boolean sendMail(String from, String to, String subject, String content, ArrayList fileAttachments, String jndiName) throws Exception{

        // Get session from context

        Context initialContext = new InitialContext();

        Session session = (Session) initialContext.lookup(jndiName);

        // Define message

        MimeMessage message = new MimeMessage(session);

        message.setFrom(new InternetAddress(from));           

        message.setSubject(subject);

        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

       

        // create the message part

        MimeBodyPart messageBodyPart = new MimeBodyPart();

        //fill message

        messageBodyPart.setContent(content, "text/html");

        Multipart multipart = new MimeMultipart();

        multipart.addBodyPart(messageBodyPart);

        if (fileAttachments != null) {

            // Part two is attachment

 

            Iterator it = fileAttachments.iterator();

            while (it.hasNext()) {

                String fileName = (String) it.next();

                messageBodyPart = new MimeBodyPart();

                DataSource source = new FileDataSource(fileName);

                String fName = fileName.replaceAll(tempDirectory, "");

                messageBodyPart.setDataHandler(new DataHandler(source));

                messageBodyPart.setFileName(fName);

                multipart.addBodyPart(messageBodyPart);

                // Put parts in message                   

            }

        }

        message.setContent(multipart);

        // Send the message

        Transport.send(message);

        return true;

}

 

JNDI Configuration for Tomcat

The highlighted line in sendMail() method is looking up in the initialContext for the JavaMail session object via a JNDI name.  Therefore, the tomcat server should provide the looking up service, which registered the JavaMail session object with the expected JNDI name. To do this, we need to create a context.xml file and save it in the META-INF folder. (Tomcat will copy this file and deploy into conf\Catalina\localhost folder and rename it to the value of docBase)

 

<Context path="/hongliang" docBase="hongliang" debug="5" reloadable="true" crossContext="true">

<Resource name="mail/Session" type="javax.mail.Session" mail.smtp.host="YOUR_MAIL_SERVER_NAME"/>

</Context>

 

The preceding code is registering an instance of javax.mail.Session to JNDI with name “mail/Session” Since all configured entries and resources are placed in the java:comp/env portion of the JNDI namespace, the parameter for initialContext.lookup() should be java:comp/env/mail/Session.

Unit Test

To run the unit test for the preceding email application, we have to simulate the tomcat server to provide the context, which we can use RefFSContextFactory to generate. You can download this library from Sun’s website or via maven

        <dependency>

            <groupId>com.sun.jndi</groupId>

            <artifactId>fscontext</artifactId>

            <version>1.2-beta-3</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>com.sun.jndi</groupId>

            <artifactId>providerutil</artifactId>

            <version>1.2</version>

            <scope>test</scope>

        </dependency>

 

System.setProperty(Context.INITIAL_CONTEXT_FACTORY,

        "com.sun.jndi.fscontext.RefFSContextFactory");

InitialContext ic = new InitialContext();

 

Once you got the InitialContext, you need to create a reference to the object and bind it to the expected name.

 

Reference ref = new Reference("javax.mail.Session", "org.apache.naming.factory.MailSessionFactory", null);

ref.add(new StringRefAddr("mailhost", "UKEXFE-LB1x"));

ref.add(new StringRefAddr("mail.smtp.host", "UKEXFE-LB1"));

ic.rebind("mail/Session", ref);

 

assertTrue(ep.sendMail("xx", "xx", "xx, "xx", attachList, “java:comp/env/mail/Session”));

 

 

A bit more about JNDI and Tomcat Setting

In the case you want to configure your data source details in the tomcat rather in spring context file, you should specify it in the context.xml file inside the tomcat config folder.

 

<Resource auth="Container"

    description="MySQLDB Connection"

    name="jdbc/MY_DATABASE"

    type="javax.sql.DataSource"

    password="hongl1ang"

    driverClassName="com.mysql.jdbc.Driver"

    validationQuery="SELECT 1"

    username="hongliang"

    url="jdbc:mysql://mysql-hongliang.com:3306/mySchema?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"

    maxActive="100"

    poolPreparedStatements="true"

    maxIdle="1"

    maxWait="120000"

    removeAbandoned="true"

    removeAbandonedTimeout="20"

    logAbandoned="false"

    defaultAutoCommit="false"/> 

 

Then you need to define the bean that reference to the preceding resource in the spring context

 

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

    <property name="jndiName" value="java:comp/env/jdbc/MY_DATABASE "/>

</bean>

 

Finally, you can inject this data source to any sessionFactory that you need.

 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource" ref="dataSource"/>

    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>

    <property name="mappingResources">

        <list>

            <value>/sql/DocumentDaoSql.hbm.xml</value>

            <value>/sql/otherSql.hbm.xml</value>

        </list>

    </property>

</bean>

 

Reference:

http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

 

 

 

 

Advertisements
This entry was posted in Java Utilities. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s