diff --git a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java index d7d617ab6d..9eacb1ef94 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java +++ b/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java @@ -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 failedMessages = new LinkedHashMap(); - 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. *

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 { diff --git a/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java b/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java index 793f7a5d28..f2c94c59d8 100644 --- a/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java +++ b/spring-context-support/src/test/java/org/springframework/mail/javamail/JavaMailSenderTests.java @@ -23,7 +23,6 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.Properties; - import javax.activation.FileTypeMap; import javax.mail.Address; import javax.mail.Message; @@ -41,6 +40,7 @@ import junit.framework.TestCase; import org.springframework.mail.MailParseException; import org.springframework.mail.MailSendException; import org.springframework.mail.SimpleMailMessage; +import org.springframework.util.ObjectUtils; /** * @author Juergen Hoeller @@ -106,7 +106,7 @@ public class JavaMailSenderTests extends TestCase { simpleMessage1.setTo("he@mail.org"); SimpleMailMessage simpleMessage2 = new SimpleMailMessage(); simpleMessage2.setTo("she@mail.org"); - sender.send(new SimpleMailMessage[] {simpleMessage1, simpleMessage2}); + sender.send(simpleMessage1, simpleMessage2); assertEquals("host", sender.transport.getConnectedHost()); assertEquals("username", sender.transport.getConnectedUsername()); @@ -152,7 +152,7 @@ public class JavaMailSenderTests extends TestCase { mimeMessage1.setRecipient(Message.RecipientType.TO, new InternetAddress("he@mail.org")); MimeMessage mimeMessage2 = sender.createMimeMessage(); mimeMessage2.setRecipient(Message.RecipientType.TO, new InternetAddress("she@mail.org")); - sender.send(new MimeMessage[] {mimeMessage1, mimeMessage2}); + sender.send(mimeMessage1, mimeMessage2); assertEquals("host", sender.transport.getConnectedHost()); assertEquals("username", sender.transport.getConnectedUsername()); @@ -210,7 +210,7 @@ public class JavaMailSenderTests extends TestCase { messages.add(mimeMessage); } }; - sender.send(new MimeMessagePreparator[] {preparator1, preparator2}); + sender.send(preparator1, preparator2); assertEquals("host", sender.transport.getConnectedHost()); assertEquals("username", sender.transport.getConnectedUsername()); @@ -425,7 +425,7 @@ public class JavaMailSenderTests extends TestCase { simpleMessage2.setTo("she@mail.org"); try { - sender.send(new SimpleMailMessage[] {simpleMessage1, simpleMessage2}); + sender.send(simpleMessage1, simpleMessage2); } catch (MailSendException ex) { ex.printStackTrace(); @@ -456,7 +456,7 @@ public class JavaMailSenderTests extends TestCase { mimeMessage2.setRecipient(Message.RecipientType.TO, new InternetAddress("she@mail.org")); try { - sender.send(new MimeMessage[] {mimeMessage1, mimeMessage2}); + sender.send(mimeMessage1, mimeMessage2); } catch (MailSendException ex) { ex.printStackTrace(); @@ -537,6 +537,7 @@ public class JavaMailSenderTests extends TestCase { this.connectedPort = port; this.connectedUsername = username; this.connectedPassword = password; + setConnected(true); } @Override @@ -552,9 +553,7 @@ public class JavaMailSenderTests extends TestCase { if ("fail".equals(message.getSubject())) { throw new MessagingException("failed"); } - List

addr1 = Arrays.asList(message.getAllRecipients()); - List
addr2 = Arrays.asList(addresses); - if (!addr1.equals(addr2)) { + if (!ObjectUtils.nullSafeEquals(addresses, message.getAllRecipients())) { throw new MessagingException("addresses not correct"); } if (message.getSentDate() == null) {