Monday, January 2, 2012

Sending E-Mail From an ADF Application Deployed on WebLogic Server.

In this post, I list the steps to send e-mails (using SMTP) from an ADF application deployed on Weblogic server. I have used JavaMail API to send e-mail on the click of a button. The steps needed to send e-mail using Java Mail API are:

1. Download JavaMail API zip, and add the mail.jar as a library to your project.
2. Create a new Mail Session, and set its JNDI Name.
3. Set appropriate properties in your mail session.
4. Access the mail session using JNDI.
5. Fetch the properties set in the mail session in your code, like from-user, from-user-password etc to send the e-mail.

The following image shows the UI page used for this post to send e-mails:



After entering the To Email ID, Subject, and Mail Text, when the Send E-Mail button is clicked, the email is send from its action listener.

To create the above UI, I created a Custom Application:




And selected ADF Faces technology in the project features section of the wizard, as shown below:



Click Finish to create the Custom App with ADF Faces compatible project with default settings.
After that, add the mail.jar to the list of project libraries as shown below:



Now, create a new page, as shown below:



In the above figure, BasePageBean is the managed bean that contains the code for the "Send E-Mail" button's action listener.
Here is the code of BasePageBean class:

package project1;

import com.sun.mail.smtp.SMTPTransport;

import java.util.Date;
import java.util.Properties;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ActionEvent;

import javax.mail.Message;
import javax.mail.Session;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import oracle.adf.view.rich.component.rich.input.RichInputText;

import javax.naming.InitialContext;

public class BasePageBean {
    private RichInputText emailIdInputText;
    private RichInputText emailSubjectInputText;
    private RichInputText mailText;
   
    String emailID = null;
    String emailSubject = null;
    String emailText = null;

    public BasePageBean() {
    }

    public void setEmailIdInputText(RichInputText emailIdInputText) {
        this.emailIdInputText = emailIdInputText;
    }

    public RichInputText getEmailIdInputText() {
        return emailIdInputText;
    }

    public void setEmailSubjectInputText(RichInputText emailSubjectInputText) {
        this.emailSubjectInputText = emailSubjectInputText;
    }

    public RichInputText getEmailSubjectInputText() {
        return emailSubjectInputText;
    }

    public void sendMail(ActionEvent actionEvent) throws Exception{
        // Add event code here...
        String emailID = getEmailID();
        String subject = getEmailSubject();
        String text = getEmailText();
       
        InitialContext ic = new InitialContext();
        Session session = (Session) ic.lookup("mail/NewMailSession");

        Properties props = session.getProperties();
        System.out.println("LKAPOOR: PROPERTIES LIST: ");
        props.list(System.out);

        String  to = emailID;
        if(to==null || to.equals(""))
            to = "lalitkapoor.mailid@gmail.com";
       
        if(subject==null || subject.equals(""))
            subject = "Test Mail";

        String mailhost = props.getProperty("mail.smtp.host");
        System.out.println("LKAPOOR:: mailhost = " + mailhost);
        String user = props.getProperty("mail.smtp.user");
        System.out.println("LKAPOOR:: user = " + user);
        String password = props.getProperty("mail.smtp.password");
        System.out.println("LKAPOOR:: password = " + password);
        String protocol = props.getProperty("mail.transport.protocol");
        System.out.println("LKAPOOR:: protocol = " + protocol);
       
        String authorization = props.getProperty("mail.smtps.auth");
        String mailDisabled = props.getProperty("mail.disable");
        String verboseProp = props.getProperty("mail.verbose");
        String debugProp = props.getProperty("mail.debug");
       
        boolean sentDisabled = false;
        if(mailDisabled.equals("true"))
            sentDisabled = true;
       
        if(!sentDisabled){
           
            boolean auth = false;
            if(authorization.equals("true"))
                auth = true;
           
            boolean verbose = false;
            if(verboseProp.equals("true"))
                verbose = true;
   
            String mailer = "smtpsend";
           
            if(debugProp.equals("true"))
                session.setDebug(true);
            else
                session.setDebug(false);
   
            System.out.println("LKAPOOR: session initialized.");
                 
            Message msg = new MimeMessage(session);
           
            msg.setFrom();      
           
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
           
            System.out.println("LKAPOOR: recipient set.");
           
            msg.setSubject(subject);
            msg.setText(text);
   
            msg.setHeader("X-Mailer", mailer);
            msg.setSentDate(new Date());
   
            System.out.println("LKAPOOR: Metadata set.");
   
            SMTPTransport t = (SMTPTransport)session.getTransport(protocol);
   
            System.out.println("LKAPOOR: Gettting Transport.");
   
            try {
                System.out.println("LKAPOOR: Before connect via authorization.");
                t.connect(mailhost, user, password);
                t.sendMessage(msg, msg.getAllRecipients());
                System.out.println("LKAPOOR: message sent.");
            } finally {
                    if (verbose)
                        System.out.println("Response: " + t.getLastServerResponse());
                    t.close();
            }
           
            System.out.println("\nMail was sent successfully.");
        }else{
            System.out.println("Mail Sending is disabled.");
        }
       
    }

    public void setMailText(RichInputText mailText) {
        this.mailText = mailText;
    }

    public RichInputText getMailText() {
        return mailText;
    }

    public void setEmailID(String emailID) {
        this.emailID = emailID;
    }

    public String getEmailID() {
        return emailID;
    }

    public void setEmailSubject(String emailSubject) {
        this.emailSubject = emailSubject;
    }

    public String getEmailSubject() {
        return emailSubject;
    }

    public void setEmailText(String emailText) {
        this.emailText = emailText;
    }

    public String getEmailText() {
        return emailText;
    }
}

The sendMail() action listener accesses the Mail Session using the JNDI URL "mail/NewMailSession".
To access this session, we need to configure a Mail Session on our WebLogic server.
To configure the Mail Session, open the WLS Home page, and click the Mail Session link:



The "Summary of Mail Sessions" page comes up. Click New to create a new Mail Session, and enter the following details:



As shown above, the action listener using the same string as JNDI URL which is entered as JNDI Name for the mail session.
Using this Mail Session, we can access the properties entered in the JavaMail Properties section in our action listener. I have entered the following properties to send an email using SMTP protocol:

mail.smtp.auth=true
mail.debug=true
mail.smtp.host=smtp.gmail.com
mail.smtp.user=lalitkapoor.mailid@gmail.com
mail.smtp.password=XXXXXXX ;)
mail.transport.protocol=smtp
mail.smtp.port=465
mail.disable=false
mail.verbose=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

So, basically, I am sending an email to myself in this example.
Click Save to deploy the changes, and run the application.
After entering the details, when you click the 'Send E-Mail' button, the e-mail is send, and here is how that mail looks like:



That's it.
When the provider doesn't support SSL for SMTP connections, like in my case, then we will hit the following error:

DEBUG SMTP: exception reading response: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
Exception in thread "main" javax.mail.MessagingException: Exception reading response;   
nested exception is:
  javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

To avoid this, remove "mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory" property from mail session and it will work fine.

Reference:
http://www.coderanch.com/t/443237/java/java/JavaMail-security