Search code examples
javalog4jsmtpappender

Must issue a STARTTLS command


I am trying to send error email through log4j. by using following appender:

 <appender name="ERROR_MAIL" class="org.apache.log4j.net.SMTPAppender">
   <param name="SMTPUsername" value="xxxxxx@gmail.com" />
    <param name="SMTPPassword" value="**********" />
    <param name="To" value="test@gmail.com"/>
    <param name="From" value="xxxxxx@gmail.com"/>
    <param name="Subject" value="Newyse Error "/>
    <param name="SMTPHost" value="smtp.gmail.com"/>
    <param name="SMTPPort" value="25" />
    <param name="BufferSize" value="10"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="[%d{ISO8601} %t %5p %c:$L]"/>
    </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
      <param name="LevelMin" value="ERROR"/>
      <param name="LevelMax" value="FATAL"/>
    </filter>
  </appender>   

but I am getting the following exception

com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. wr9sm43519864pbc.7 - gsmtp

from several other question I understood that I need to add the following property in the smtpAppender

props.put("mail.smtp.starttls.enable", "true");

So how we can add it to the existing SMTPAppender ?


Solution

  • Many Thanks to @Jk1 to give me the answer that lands me to get the working code with configuration mentioned in the question.

    import java.util.Date;
    import java.util.Properties;
    
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Multipart;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMultipart;
    
    import org.apache.log4j.Layout;
    import org.apache.log4j.helpers.LogLog;
    import org.apache.log4j.net.SMTPAppender;
    import org.apache.log4j.spi.LoggingEvent;
    
    import com.sun.mail.smtp.SMTPTransport;
    
    /**
     * Extension of Log4j {@link SMTPAppender} for Gmail support
     * 
     */
    public class SecureSMTPAppender extends SMTPAppender
    {
      /**
       * Cached session for later use i.e. while sending emails
       */
      protected Session session;
    
      public SecureSMTPAppender()
      {
        super();
      }
    
      /**
       * Create mail session.
       * 
       * @return mail session, may not be null.
       */
      protected Session createSession()
      {
        Properties props = new Properties();
        props.put("mail.smtps.host", getSMTPHost());
        props.put("mail.smtps.auth", "true");
    
        Authenticator auth = null;
        if (getSMTPPassword() != null && getSMTPUsername() != null)
        {
          auth = new Authenticator()
          {
            protected PasswordAuthentication getPasswordAuthentication()
            {
              return new PasswordAuthentication(getSMTPUsername(), getSMTPPassword());
            }
          };
        }
        session = Session.getInstance(props, auth);
        if (getSMTPDebug())
        {
          session.setDebug(getSMTPDebug());
        }
        return session;
      }
    
      /**
       * Send the contents of the cyclic buffer as an e-mail message.
       */
      protected void sendBuffer()
      {
        try
        {
          MimeBodyPart part = new MimeBodyPart();
    
          StringBuffer sbuf = new StringBuffer();
          String t = layout.getHeader();
          if (t != null)
            sbuf.append(t);
          int len = cb.length();
          for (int i = 0; i < len; i++)
          {
            LoggingEvent event = cb.get();
            sbuf.append(layout.format(event));
            if (layout.ignoresThrowable())
            {
              String[] s = event.getThrowableStrRep();
              if (s != null)
              {
                for (int j = 0; j < s.length; j++)
                {
                  sbuf.append(s[j]);
                  sbuf.append(Layout.LINE_SEP);
                }
              }
            }
          }
    
          t = layout.getFooter();
          if (t != null)
            sbuf.append(t);
          part.setContent(sbuf.toString(), layout.getContentType());
    
          Multipart mp = new MimeMultipart();
          mp.addBodyPart(part);
          msg.setContent(mp);
    
          msg.setSentDate(new Date());
          send(msg);
        } catch (Exception e)
        {
          LogLog.error("Error occured while sending e-mail notification.", e);
        }
      }
    
      /**
       * Pulled email send stuff i.e. Transport.send()/Transport.sendMessage(). So
       * that on required this logic can be enhanced.
       * 
       * @param msg
       *          Email Message
       * @throws MessagingException
       */
      protected void send(Message msg) throws MessagingException
      {
        SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
        try
        {
          t.connect(getSMTPHost(), getSMTPUsername(), getSMTPPassword());
          t.sendMessage(msg, msg.getAllRecipients());
        } finally
        {
          System.out.println("Response: " + t.getLastServerResponse());
          t.close();
        }
      }
    }