java - MimeMessage.saveChanges es realmente lento
junit javamail (1)
La siguiente prueba tarda unos 5 segundos en ejecutarse debido a la inclusión de m.saveChanges()
.
import org.junit.Before;
import org.junit.Test;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Test
public void test1() throws MessagingException, IOException {
Session s = Session.getDefaultInstance(new Properties());
MimeMessage m = new MimeMessage(s);
m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
m.saveChanges();
assertEquals(m.getContent(), "<b>Hello</b>");
assertEquals(m.getContentType(), "text/html; charset=utf-8");
}
También me he burlado de la sesión con mockito, pero no ayuda:
Session s = mock(Session.class);
when(s.getProperties()).thenReturn(new Properties());
¿Cuál es el problema aquí? ¿De qué me puedo fingir para acelerar las cosas?
Solucione los errores más comunes que las personas cometen al usar JavaMail en su código primero.
La búsqueda DNS puede dañar el rendimiento en algunas máquinas. Para el JDK, puede cambiar las propiedades de seguridad para el almacenamiento en caché de la búsqueda de DNS sun.net.inetaddr.ttl
y sun.net.inetaddr.negative.ttl
o establecer las propiedades del sistema sun.net.inetaddr.ttl
y sun.net.inetaddr.negative.ttl
. El comportamiento predeterminado en JDK 7 y posteriores hace un buen trabajo de almacenamiento en caché.
Preferiblemente, puede usar las propiedades de la sesión para evitar algunas de estas búsquedas.
- Establezca la propiedad de sesión para
mail.smtp.localhost
para evitar la búsqueda de nombres en el comando HELO. - Establezca la propiedad de sesión para
mail.from
omail.host
(no las versiones de protocolo) ya que eso evitará la búsqueda de nombre enInternetAddress.getLocalAddress(Session)
. Llamar aMimeMessage.saveChanges()
,MimeMessage.updateHeaders()
,MimeMessage.updateMessageID()
oMimeMessage.setFrom()
activará este método. - Establezca la propiedad de sesión para
mail.smtp.from
para evitar la búsqueda en el comando EHLO. - Alternativamente, puede establecer la propiedad del sistema
mail.mime.address.usecanonicalhostname
enfalse
si su código se basa ensetFrom()
pero esto debe ser manejado por el punto # 2. - Para IMAP, puede intentar establecer
mail.imap.sasl.usecanonicalhostname
enfalse
que es el valor predeterminado.
Como no está transportando un mensaje, aplique la regla n. ° 2 cambiando su código a:
@Test
public void test1() throws MessagingException, IOException {
Properties props = new Properties();
props.put("mail.host", "localhost");
Session s = Session.getInstance(props);
MimeMessage m = new MimeMessage(s);
m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
m.saveChanges();
assertEquals(m.getContent(), "<b>Hello</b>");
assertEquals(m.getContentType(), "text/html; charset=utf-8");
}