tags:

views:

731

answers:

3

I copied code from here only to send mails using the Gmail SMTP server. But I'm getting security exceptions. I achieved the target once I succeeded in sending 4 mails but later I made few changes in my code as per my application demand and it's throwing security exception. I'm sure it will work but having some problems.

What is the trouble with this code?

The code is:

    package com.ibm.lims;

    import java.security.Security;
    import java.util.Properties;

    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Multipart;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;

    public class mails {
        private static final String SMTP_HOST_NAME = "smtp.gmail.com";
        private static final String SMTP_PORT = "465";
        //private static final String emailMsgTxt = "robin borrowed a book";
        //private static final String emailSubjectTxt = "online library management system notification";
        private static final String emailFromAddress = "[email protected]";
        private static final String SSL_FACTORY ="javax.net.ssl.SSLSocketFactory";
        //private static final String[] sendTo = {"[email protected]","[email protected]"};

        public static void mailer(String[] sendTo,String emailSubjectTxt,String emailMsgTxt) throws Exception{
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

            new mails().sendSSLMessage(sendTo,emailSubjectTxt,emailMsgTxt,emailFromAddress);
            System.out.println("Sucessfully Sent mail to All Users");
        }

        public void sendSSLMessage(String[] recipients,String subject,String message,String from) throws MessagingException {
            boolean debug = true;

            Properties props = new Properties();
            props.put("mail.smtp.host", SMTP_HOST_NAME);
            props.put("mail.smtp.auth", "true");
            props.put("mail.debug", "true");
            props.put("mail.smtp.port", SMTP_PORT);
            props.put("mail.smtp.socketFactory.port", SMTP_PORT);
            props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
            props.put("mail.smtp.socketFactory.fallback", "false");

            Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("[email protected]","weakpaasword");
                }
            }
        );

        MimeMessage message1 =new MimeMessage(session);
        message1.setFrom(new InternetAddress(from));
        for(int i=0;i<=recipients.length;i++){
            message1.addRecipient(Message.RecipientType.TO,new InternetAddress(recipients[i]));
        }

        message1.setSubject(subject);

        // Create the message part.
        MimeBodyPart messageBodyPart =new MimeBodyPart();

        //Fill message.
        messageBodyPart.setText(message);

        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);

        // Part two is attachment.

        // Put parts in message
        message1.setContent(multipart);

        // Send the message
        Transport.send( message1 );
        }

    }

I used to call it from JSP as:

    <%
        String requestedopration = request.getParameter("operation");
        if("Borrow".equalsIgnoreCase(requestedopration)){
            Borrow borrow = new Borrow();
            borrow.setBook_id(request.getParameter("bookid"));
            borrow.setUser_id((String)session.getAttribute("userid"));

            boolean c=LimsHandler.getInstance().borrowbook(borrow);
            if(c){
            final String[] sendTo = {"[email protected]","[email protected]"};

        mails.mailer(sendTo,"lims notification","robin borrowed a book");

    %>

But I am getting security exceptions. I'm getting exception as:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception
org.apache.jasper.JasperException: java.lang.ArrayIndexOutOfBoundsException: 2
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:413)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)

root cause
java.lang.ArrayIndexOutOfBoundsException: 2
    com.ibm.lims.mails.sendSSLMessage(mails.java:64)
    com.ibm.lims.mails.mailer(mails.java:35)
    org.apache.jsp.borrow_jsp._jspService(borrow_jsp.java:144)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)

note The full stack trace of the root cause is available in the Apache Geronimo (Embedded Tomcat/6.0.20-20090724) logs.
Apache Geronimo (Embedded Tomcat/6.0.20-20090724)
+1  A: 

From JDK 1.4.0 on you don't need to specify the SSL provider because it is built into the JDK. Take a look at Sun's explanation and examples of how to use GMail through JavaMail:

Ichorus
A: 

It doesn't look like you have the mail transport protocol set for ssl. Try adding props.put("mail.transport.protocol","smtps");. Based on this snippet from the JavaMail site, you may need to add "mail.smtps.auth","true" as well.

String host = "smtp.gmail.com;
String username = "user";
String password = "passwd";
Properties props = new Properties();
props.put("mail.smtps.auth", "true");
// ...
MimeMessage msg = new MimeMessage(session);
// set the message content here
Transport t = session.getTransport("smtps");
try {
t.connect(host, username, password);
t.sendMessage(msg, msg.getAllRecipients());
} finally {
t.close();
}

Yes, the methods are different, but the same properties are used.

ucbpaladin
Sorry, the mail.transport.protocol property doesn't seem to affect anything in a quick unit test...looking at the java mail source code, it looked like it would. session.setProtocolForAddress("rfc822","smtps") does the trick, although this can also be set in properties files.
ucbpaladin
actually i was able to send the mails.i sent 4 5 mails.but later exception occured.is that a server problem.String[] recipients was written as String reciepients[] in the code provided by this site.i changed that is that the reason???
Robin Agrahari
A: 

Your code seems to be fine except that looping is wrong. Use "<" instead of "<=" then you won't get ArrayIndexOutOfBoundException.

for (int i = 0; i < recipients.length; i++) {
    message1.addRecipient(Message.RecipientType.TO,
    new InternetAddress(recipients[i]));
}
Venkat
plz help the problem still exist.
Robin Agrahari
Edited answer section. Use "<" instead of "<=" then you won't get ArrayIndexOutOfBoundException.
Venkat