JavaMail SMTP-host error

2019-08-06 09:49发布

问题:

I have a Grails-application that sends emails. The mailserver has no SMTP-authentication, so it requires "POP before SMTP", which means that I need to authenticate against the POP-account before sending through SMTP. Most often it works, but then once in a while, the mailserver is not picked up from the properties, and it tries to connect to "localhost" instead. Here is the properties:

    Properties props = new Properties();

    props.setProperty("mail.store.protocol", "pop3")
    props.setProperty("mail.pop3.host", "mail.xxxxx.com")
    props.setProperty("mail.pop3.port", "110")
    props.setProperty("mail.smtp.host", "mail.xxxxx.com")
    props.setProperty("mail.smtp.port", "25")
    props.setProperty("mail.smtp.sendpartial", "true")
    props.setProperty("mail.pop3.socketFactory.port", "110")
    props.setProperty("mail.pop3.socketFactory.class","javax.net.SocketFactory")
    props.setProperty("mail.pop3.socketFactory.fallback", "false")
    Transport t = null
    def store

    try {
        URLName url = new URLName("pop3", "mail.xxxxxxx.com", 110, 
             "INBOX",  "username", "password");

        Session session = Session.getDefaultInstance(props, null)

        store = session.getStore(url)
        store.connect("mail.xxxxxx.com", "username", "password")

        Message message = new MimeMessage(session);

        message.setFrom(new InternetAddress("xxxx@xxxxxx.com"));

        message.setRecipients(Message.RecipientType.TO, 
            InternetAddress.parse(toAddress, true));

        message.setSubject(mailTitle);
        message.setContent(messageBody, "text/html");
        message.setSentDate(new Date());

        t = session.getTransport("smtp")
        t.connect()
        t.send(message)
        return true
    }
    catch (AddressException e) {
        e.printStackTrace()
        return false
    }
    catch (MessagingException e) {
        e.printStackTrace()
        return false
    }
    finally {
        store?.close()
    }

More often than not, this works. But when a Quartz Job is doing the sending, the mailserver entry from the Properties is not honored and it uses "localhost" instead and then fails to send the emails.

I can connect with Telnet and send with the attributes mentioned.

Could it be a timeout issue? According to what I've read in docs, the timeouts are "infinite" as default, so that "should" not be the problem.

Could it be a performance issue? I've created a "dummy app", which - more or less - does the same, but does not issue the sending from a Grails service, but directly from a controller. That one works all the time, but that app is always idleing.

I'm not using the Mail Plugin for Grails, since I couldn't see that it could handle the "pop before smtp"-paradigm.

Thanks in advance.

回答1:

Solution: It looks as though the solution is to put the "mail.smtp.localhost"-value to the same value as for "mail.smtp.host". Not one single mail has failed since I put that property in. I don't think it was an obvious property to set and an ignorance from my point of view, nevertheless, I hope this will help someone else in the future.

So, my properties are as follows:

    Properties props = new Properties();

    props.setProperty("mail.store.protocol", "pop3")
    props.setProperty("mail.pop3.host", "mail.xxxxxxx.com")
    props.setProperty("mail.pop3.port", "110")
    props.setProperty("mail.smtp.localhost", "mail.xxxxxxx.com")
    props.setProperty("mail.smtp.host", "mail.xxxxxxx.com")
    props.setProperty("mail.smtp.port", "25")
    props.setProperty("mail.smtp.sendpartial", "true")
    props.setProperty("mail.pop3.socketFactory.port", "110")
    props.setProperty("mail.pop3.socketFactory.class","javax.net.SocketFactory")
    props.setProperty("mail.pop3.socketFactory.fallback", "false")

Setting the value of "mail.smtp.host" to the property "mail.smtp.localhost", not only made the errors go away, the entire routine became a lot faster.

Thank you for your efforts!



回答2:

        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.port", "25");
        props.setProperty("mail.host", "a.b.com");
        props.setProperty("mail.smtp.timeout", "10000");

Above works