0
votes

I cannot understand what I'm missing in Javamail configuration. I'm a bit confused about "protocol" part of properties key.

This is my SMTP code:

public Session getSendSession(){
        Properties props = new Properties();
        String protocol="smtps";
        props.put("mail.host", "smtp.myserver.com");
        props.put("mail.transport.protocol", protocol);
        props.put("mail."+protocol+".port", 587);
        if(protocol!=null && protocol.toLowerCase().endsWith("s")){
            props.put("mail."+protocol+".ssl.enable","true");
            try {
                MailSSLSocketFactory sf = new MailSSLSocketFactory();
                sf.setTrustAllHosts(true);
                props.put("mail."+protocol+".ssl.socketFactory", sf);
            } catch (GeneralSecurityException e) {
                throw new SystemException(e);
            }
            props.put("mail."+protocol+".ssl.trust","*");
        }
        props.put("mail."+protocol+".auth", "true");
        Session mailSession= Session.getInstance(props, 
            new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("[email protected]","test");
                }
            });
        mailSession.setDebug(true);
        return mailSession;
    }

This is the debug output of Props:

{mail.smtps.ssl.enable=true, mail.transport.protocol=smtps, mail.smtps.port=587, mail.smtps.ssl.trust=*, mail.smtps.auth=true, mail.host=smtp.myserver.com, mail.smtps.ssl.socketFactory=com.sun.mail.util.MailSSLSocketFactory@cfa4b2}

With this configuration I got this debug output:

DEBUG: setDebug: JavaMail version 1.4.7
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.myserver.com", port 25, isSSL false

As you see the ssl and port configuration is ignored!


If I change the protocol part of each properties with simply "smtp" (without "s") the connection success:

public Session getSendSession(){
    Properties props = new Properties();
    String protocol="smtps";
    props.put("mail.host", "smtp.myserver.com");
    props.put("mail.transport.protocol", protocol);
    props.put("mail.smtp.port", 587);
    if(protocol!=null && protocol.toLowerCase().endsWith("s")){
        props.put("mail.smtp.ssl.enable","true");
        try {
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.socketFactory", sf);
        } catch (GeneralSecurityException e) {
            throw new SystemException(e);
        }
        props.put("mail.smtp.ssl.trust","*");
    }
    props.put("mail.smtp.auth", "true");
    Session mailSession= Session.getInstance(props, 
        new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("[email protected]","test");
            }
        });
    mailSession.setDebug(true);
    return mailSession;
}

Props debug:

{mail.smtp.port=587, mail.smtp.ssl.trust=*, mail.transport.protocol=smtps, mail.smtp.auth=true, mail.smtp.ssl.enable=true, mail.host=smtp.myserver.com, mail.smtp.ssl.socketFactory=com.sun.mail.util.MailSSLSocketFactory@45760}

Debug output:

DEBUG: setDebug: JavaMail version 1.4.7
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.myserver.com", port 587, isSSL true

I also looked into javamail source and seems that the properties is read with the "mail."+(protocol/name)+".value" as expected. What I'm missing?

What I'm missing?

1
i did not find and answer, but I found that Transport.send() ignore the mail.transport.protocol property and choose its protocol only by mail address type and always gets "smtp".Tobia

1 Answers

0
votes

The property names need to match the protocol name you pass to Session.getTransport or Session.getStore. As you discovered, Transport.send chooses the protocol based on the address types used in the message (almost always "rfc822", and thus the "smtp" protocol). You can change the mapping from address type to protocol if you need to, but the simpler approach is to just set properties for the "smtp" protocol. And you don't need to use MailSSLSocketFactory if you're setting the mail.smtp.ssl.trust property.

Also, you're using a very old version of JavaMail. The current version is 1.6.2, please upgrade if possible.