breakline
breakline

Reputation: 6073

Spring+JavaMail sending timeout

I'm trying to send an email with Spring and JavaMail. Since I'm behind a proxy it probably shouldn't work, but I'd like to have a timeout because now javamail just hangs for who knows how long.

This is my mailsender config in my spring xml:

<bean id="gmailMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host"><value>smtp.gmail.com</value></property>
    <property name="port"><value>465</value></property>
    <property name="protocol"><value>smtp</value></property>
    <property name="username"><value>[email protected]</value></property>
    <property name="password"><value>XXXXXXX</value></property>
    <property name="javaMailProperties">
        <props>
            <prop key="mail.smtp.auth">true</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
            <prop key="mail.smtp.quitwait">false</prop>
            <prop key="mail.smtp.socketFactory.port">465</prop>
            <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
            <prop key="mail.smtp.socketFactory.fallback">false</prop>
            <prop key="mail.smtp.connectiontimeout">1000</prop>
            <prop key="mail.debug">true</prop>
        </props>
    </property>
</bean>

When I send a mail I get the following debug output:

DEBUG: JavaMail version 1.5.4
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL false

Then it hangs there.

After like 5 minutes I get the:

javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465, response: -1

exception.

Now I don't really want to know if it hangs because of proxy or firewall issues, I just want it to timeout after a short time if anything isnt working. Why isn't mail.smtp.connectiontimeout settings working properly?

Upvotes: 7

Views: 15730

Answers (3)

julianm
julianm

Reputation: 2711

Same answer as above but showing alternative to YML and XML props.

You can build the props in the code as well :

@Bean
public JavaMailSender getJavaMailSender() {

    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

    mailSender.setHost(host);
    mailSender.setPort(port);
    mailSender.setUsername(username);
    mailSender.setPassword(password);

    Properties props = mailSender.getJavaMailProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth", auth);
    props.put("mail.smtp.starttls.enable", starttls);
    props.put("mail.smtp.timeout", 5000);
    props.put("mail.smtp.connectiontimeout", 5000);
    props.put("mail.smtp.writetimeout", 5000);
    props.put("mail.debug", debug);

    return mailSender;
}

After 5000ms I got this log:

2020-08-11 14:43:39.291 ERROR 117828 --- [         task-1] p.home.phe.adapter.smtp.SMTPAdapter      : EmailNotification sending failure :Couldn't connect to host, port: 192.168.28.45, 25; timeout 5000

Please note Exception is catched in my errorhandler, not in the code above.

Upvotes: 4

Pramuditha
Pramuditha

Reputation: 728

You can set timeouts in the property file. Disable firewall or virus guards and try it again.

# Other properties
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=10000
spring.mail.properties.mail.smtp.timeout=10000
spring.mail.properties.mail.smtp.writetimeout=10000

Upvotes: 8

breakline
breakline

Reputation: 6073

Okay, I figured it out, so if anyone needs the same:

You also need to set the:

<prop key="mail.smtp.timeout">1000</prop>

property. Then it times out on socket read if the port is unreachable.

Upvotes: 8

Related Questions