2

We have socket application which sends out quite a number of email out. So we decided to send huge number message into it which will trigger emails. Eventually we see the email are taking hours before it reach any of the inboxes either gmail,hotmail or yahoo etc. We have this codes in the begining.

public class commuSe {
  BoneCP connectionPool = null;
  class ConnectionHandler implements Runnable {

   private Socket receivedSocketConn1;
    ConnectionHandler(Socket receivedSocketConn1) {
      this.receivedSocketConn1=receivedSocketConn1;
    }
    public void run() {
     .....
    }
    void sendClientEmail(String emailMessageString)
     {
      try 
      {
          Properties props = new Properties();      
          props.put("mail.smtp.host", "**********");        
          props.put("mail.smtp.socketFactory.port", "******");      
          //props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");        
          props.put("mail.smtp.auth", "true");      
          props.put("mail.smtp.port", "*****");         
          Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator()
          {             
            protected PasswordAuthentication getPasswordAuthentication() 
            {                   
            return new PasswordAuthentication("*********","*******");               
            }       
          });
            int count=0;
            System.out.println("\n\nClient Email queue took ready :"+emailMessageString);
               try 
               {
                    String[] eMArray = null;
                    eMArray = emailMessageString.split("@EmL@");
                    Message emailMessage = new MimeMessage(session);            
                    emailMessage.setFrom(new InternetAddress("****************"));
                    if(eMArray.length>1)
                    {
                     for(int iEmail=1; iEmail<eMArray.length ; iEmail++)
                     {
                      String cc1 = eMArray[iEmail];
                      emailMessage.addRecipient(Message.RecipientType.TO,new InternetAddress(cc1));
                     }                          
                     emailMessage.setRecipients(Message.RecipientType.BCC,InternetAddress.parse("**************"));
                    }
                    else
                    {
                     emailMessage.setRecipients(Message.RecipientType.TO,InternetAddress.parse("*************"));   
                    }
                    emailMessage.setSubject("Alerts");
                    emailMessage.setText(eMArray[0]);
                    Transport.send(emailMessage);
               }
               catch (Exception e) 
               {
               System.out.println("Transport Problem");
               e.printStackTrace();
               } 
       }
        catch (Exception e) 
       {
        System.out.println("Main email try got problem");
        e.printStackTrace();
       }     
     }
}

So based on this link How to Send bulk mails using javax.mail API efficiently? & Can we use reuse authenticated sessions to improve speed? we tried to change it as following. But end up with the mail exception. We tried to build just one session and keep reusing so avoid the mail delivery delay. We declare this at the top Session session = null; to store the session created?

public class commuSe {
      BoneCP connectionPool = null;
       Session session = null;
      class ConnectionHandler implements Runnable {

       private Socket receivedSocketConn1;
        ConnectionHandler(Socket receivedSocketConn1) {
          this.receivedSocketConn1=receivedSocketConn1;
        }
        public void run() {
         .....
        }
        void sendClientEmail(String emailMessageString)
         {
          try 
          {
                              int count=0;
                System.out.println("\n\nClient Email queue took ready :"+emailMessageString);
                   try 
                   {
                        String[] eMArray = null;
                        eMArray = emailMessageString.split("@EmL@");
                        Message emailMessage = new MimeMessage(session);            
                        emailMessage.setFrom(new InternetAddress("****************"));
                        if(eMArray.length>1)
                        {
                         for(int iEmail=1; iEmail<eMArray.length ; iEmail++)
                         {
                          String cc1 = eMArray[iEmail];
                          emailMessage.addRecipient(Message.RecipientType.TO,new InternetAddress(cc1));
                         }                          
                         emailMessage.setRecipients(Message.RecipientType.BCC,InternetAddress.parse("**************"));
                        }
                        else
                        {
                         emailMessage.setRecipients(Message.RecipientType.TO,InternetAddress.parse("*************"));   
                        }
                        emailMessage.setSubject("Alerts");
                        emailMessage.setText(eMArray[0]);
                        Transport t = session.getTransport();
                        t.connect();
                        t.sendMessage(emailMessage, emailMessage.getAllRecipients());                       }
                   catch (Exception e) 
                   {
                   System.out.println("Transport Problem");
                   e.printStackTrace();
                   } 
           }
            catch (Exception e) 
           {
            System.out.println("Main email try got problem");
            e.printStackTrace();
           }     
         }
    }
     public static void main(String[] args) {
     new commuSe ();
   }
   commuSe () {
     Properties props = new Properties();      
              props.put("mail.smtp.host", "**********");        
              props.put("mail.smtp.socketFactory.port", "******");      
              //props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");        
              props.put("mail.smtp.auth", "true");      
              props.put("mail.smtp.port", "*****");         
              session = Session.getInstance(props,new javax.mail.Authenticator()
              {             
                protected PasswordAuthentication getPasswordAuthentication() 
                {                   
                return new PasswordAuthentication("*********","*******");               
                }       
              });

   }

Stack trace is as below.

javax.mail.NoSuchProviderException: Invalid protocol: null
at javax.mail.Session.getProvider(Session.java:440)
at javax.mail.Session.getTransport(Session.java:659)
at javax.mail.Session.getTransport(Session.java:640)
at javax.mail.Session.getTransport(Session.java:626)
at commuSe $ConnectionHandler.sendEmail(commuSe .java:26028)
at commuSe $ConnectionHandler.run(commuSe .java:4734)
at java.lang.Thread.run(Thread.java:722)  
Community
  • 1
  • 1
new14
  • 703
  • 1
  • 10
  • 16
  • prop.put("mail.smtp.gmail", host); prop.put("mail.smtp.starttls.enable", "true"); prop.put("mail.smtp.host", host); prop.put("mail.smtp.user", from); prop.put("mail.smtp.password", pass); prop.put("mail.smtp.port", "587"); prop.put("mail.smtp.auth", "true"); – suresh manda Jul 11 '13 at 11:10
  • @sureshmandabut I dont get the gmail settings is cause we have our own email server. Thank you. – new14 Jul 11 '13 at 12:18

1 Answers1

6

You've made at least two of these common JavaMail mistakes. Fix them and see if that helps. If it doesn't, update your post with the new code and the details of the exception you're getting, including the stack trace.

Bill Shannon
  • 29,579
  • 6
  • 38
  • 40
  • I have added the stack trace and done the change 1) session = Session.getInstance(props,new javax.mail.Authenticator() 2) Transport t = session.getTransport(); t.connect(); t.sendMessage(emailMessage, emailMessage.getAllRecipients()); but yet the same error no difference what else should I change ya? – new14 Jul 12 '13 at 15:11
  • 1
    Normally JavaMail figures out what protocol to use for the default Transport by reading configuration files in the JavaMail jar file. If you've extracted the class files from the JavaMail jar file and included them in your application jar file, that would cause this problem. Or, if you're running in an environment where the class loader doesn't work properly, that would cause this problem. Try using session.getTransport("smtp"). – Bill Shannon Jul 12 '13 at 19:36
  • I changed further codes where at very top I set this now Session mailSession = null; static Transport transport ; String emailUsername = "********"; String emailPassword = "******"; and in side the function I call this now transport = mailSession.getTransport("smtp"); transport.connect(emailUsername, emailPassword); transport.sendMessage(emailMessage, emailMessage.getAllRecipients()); . The change of the smtp is working now. I never extracted any class file from the JavaMail I just put the .jar file in the /usr/java/jdk1.7.0_03/jre/lib/ext folder. – new14 Jul 12 '13 at 19:47
  • My problem now is the deliver is quite slow so how can I improve on the speed? – new14 Jul 12 '13 at 19:51
  • 1
    Define "slow". What have you measured? Did you see [this FAQ entry](http://www.oracle.com/technetwork/java/javamail/faq/index.html#rptsend)? (It's probably better to post a new topic for your new question.) – Bill Shannon Jul 13 '13 at 00:04
  • When I say slow means at times I could only send say 30 to 50 message where as my queue in waiting is more then few hundred. Can I speed this up at this level or I need to configure the smtp server for this ? In fact I have now put this whole statement transport.connect(emailUsername, emailPassword); into main rather then in the said function to send out email yet no improvements? Does msg.saveChanges help? – new14 Jul 13 '13 at 00:50
  • 1
    30 to 50 messages per second? Per minute? Per hour? It's not uncommon for SMTP servers to throttle you and limit the number of messages you can send. Check your server configuration or check with your server vendor. If you're running your own server, you should be able to turn off any throttling. If you're contracting with someone else for that service, you may need to pay for a higher level of service. – Bill Shannon Jul 13 '13 at 22:53
  • so meaning that now the limit lies at the SMTP right nothing else on my codes can be adjust further? Thank you for the confirmation. So I guess the java mail is not enforcing this limitation am I correct here? What is your comment about my new method of the codes where I run the statement transport.connect(emailUsername, emailPassword); into main rather then in the said function to send out email – new14 Jul 14 '13 at 12:40
  • 1
    JavaMail enforces no limit. It shouldn't matter where you put the connect call. It **does** matter whether you use the connection for one message or multiple messages. If you have a lot of messages to send, it will be more efficient to send them using one connection. If the server starts throttling you, it **might** help to drop the connection and create a new one, depending on how smart the server is. – Bill Shannon Jul 15 '13 at 18:50
  • So how to know when the server start to throttle very interesting indeed ? So since I am sending multiple message it will be helpful to remain with my latest changes then. – new14 Jul 16 '13 at 17:35
  • You should talk to your server administrator or vendor to find out what kind of throttling they do, if any. – Bill Shannon Jul 17 '13 at 22:10
  • Yes, the limit of how many messages you can send per unit time or per connection. – Bill Shannon Jul 24 '13 at 22:11