JavaMailSenderImpl catches Exception instead of MessagingException and checks for reconnect in case of message batches

Issue: SPR-12298
This commit is contained in:
Juergen Hoeller
2014-10-06 15:37:08 +02:00
parent 12a2813e2a
commit b7faef0103
2 changed files with 73 additions and 39 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -330,7 +330,7 @@ public class JavaMailSenderImpl implements JavaMailSender {
try {
return new MimeMessage(getSession(), contentStream);
}
catch (MessagingException ex) {
catch (Exception ex) {
throw new MailParseException("Could not parse raw MIME content", ex);
}
}
@@ -385,35 +385,40 @@ public class JavaMailSenderImpl implements JavaMailSender {
* in case of failure when sending a message
*/
protected void doSend(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
String username = getUsername();
String password = getPassword();
if ("".equals(username)) { // probably from a placeholder
username = null;
if ("".equals(password)) { // in conjunction with "" username, this means no password to use
password = null;
}
}
Map<Object, Exception> failedMessages = new LinkedHashMap<Object, Exception>();
Transport transport;
try {
transport = getTransport(getSession());
transport.connect(getHost(), getPort(), username, password);
}
catch (AuthenticationFailedException ex) {
throw new MailAuthenticationException(ex);
}
catch (MessagingException ex) {
// Effectively, all messages failed...
for (int i = 0; i < mimeMessages.length; i++) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessages[i]);
failedMessages.put(original, ex);
}
throw new MailSendException("Mail server connection failed", ex, failedMessages);
}
Transport transport = null;
try {
for (int i = 0; i < mimeMessages.length; i++) {
// Check transport connection first...
if (transport == null || !transport.isConnected()) {
if (transport != null) {
try {
transport.close();
}
catch (Exception ex) {
// Ignore - we're reconnecting anyway
}
transport = null;
}
try {
transport = connectTransport();
}
catch (AuthenticationFailedException ex) {
throw new MailAuthenticationException(ex);
}
catch (Exception ex) {
// Effectively, all remaining messages failed...
for (int j = i; j < mimeMessages.length; j++) {
Object original = (originalMessages != null ? originalMessages[j] : mimeMessages[j]);
failedMessages.put(original, ex);
}
throw new MailSendException("Mail server connection failed", ex, failedMessages);
}
}
// Send message via current transport...
MimeMessage mimeMessage = mimeMessages[i];
try {
if (mimeMessage.getSentDate() == null) {
@@ -427,7 +432,7 @@ public class JavaMailSenderImpl implements JavaMailSender {
}
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
}
catch (MessagingException ex) {
catch (Exception ex) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
failedMessages.put(original, ex);
}
@@ -435,9 +440,11 @@ public class JavaMailSenderImpl implements JavaMailSender {
}
finally {
try {
transport.close();
if (transport != null) {
transport.close();
}
}
catch (MessagingException ex) {
catch (Exception ex) {
if (!failedMessages.isEmpty()) {
throw new MailSendException("Failed to close server connection after message failures", ex,
failedMessages);
@@ -453,11 +460,39 @@ public class JavaMailSenderImpl implements JavaMailSender {
}
}
/**
* Obtain and connect a Transport from the underlying JavaMail Session,
* passing in the specified host, port, username, and password.
* @return the connected Transport object
* @throws MessagingException if the connect attempt failed
* @since 4.1.2
* @see #getTransport
* @see #getHost()
* @see #getPort()
* @see #getUsername()
* @see #getPassword()
*/
protected Transport connectTransport() throws MessagingException {
String username = getUsername();
String password = getPassword();
if ("".equals(username)) { // probably from a placeholder
username = null;
if ("".equals(password)) { // in conjunction with "" username, this means no password to use
password = null;
}
}
Transport transport = getTransport(getSession());
transport.connect(getHost(), getPort(), username, password);
return transport;
}
/**
* Obtain a Transport object from the given JavaMail Session,
* using the configured protocol.
* <p>Can be overridden in subclasses, e.g. to return a mock Transport object.
* @see javax.mail.Session#getTransport(String)
* @see #getSession()
* @see #getProtocol()
*/
protected Transport getTransport(Session session) throws NoSuchProviderException {