JavaMail не отправляет тему или из-под пристани: запуск войны

Кто-нибудь видел, как JavaMail не отправляет правильные сообщения MimeMessages на SMTP-сервер, в зависимости от того, как запущена JVM? В конце концов, я не могу отправлять SMTP-сообщения JavaMail с полями Subject: или From:, и, похоже, другие заголовки отсутствуют, только когда приложение запущено как война.

Веб-проект построен с помощью Maven, и я тестирую отправку JavaMail с помощью браузера и простого mail.jsp для отладки и просмотра другого поведения при запуске приложения с помощью:

1) mvn jetty: run (почта отправляется нормально, с правильными полями Тема и От)

2) mvn jetty: run-war (почта отправляется нормально, но отсутствуют поля Тема, От и другие)

Я тщательно выполнил diff для (подробного) вывода отладки Maven (-X), и между ними нет никаких различий в зависимостях времени выполнения. Я также сравнил свойства системы, и они идентичны. Что-то еще происходит в случае с причалом: запуск войны, который меняет поведение JavaMail. Какие еще камни нуждаются в точении?

Любопытно, что я пробовал использовать отладчик в обеих ситуациях и обнаружил, что экземпляр javax.mail.internet.MimeMessage создается по-разному. Веб-приложение использует Spring для отправки электронной почты, выбранной из очереди Apache ActiveMQ. При запуске приложения как mvn jetty:run переменная MimeMessage.contentStream используется для содержимого сообщения. При запуске как mvn jetty:run-war переменная MimeMessage.content используется для содержимого сообщения, а content = ASCIIUtility.getBytes (is); call удаляет все данные заголовка из проанализированного содержимого. Поскольку это казалось очень странным, а отладка Spring / ActiveMQ - это глубокое погружение, я создал упрощенный тест без какой-либо этой инфраструктуры: просто JSP с использованием mail-1.4.2.jar, но те же заголовки отсутствуют.

Также следует отметить, что эти заголовки отсутствуют при запуске файла WAR в Tomcat 5.5.27. Tomcat при запуске WAR ведет себя так же, как Jetty, с теми же отсутствующими заголовками.

При включенной отладке JavaMail я ясно вижу другой результат.

ХОРОШИЙ СЛУЧАЙ: На причале: запустить (не WAR) вывод журнала:

DEBUG: JavaMail version 1.4.2
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,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "mail.authsmtp.com", port 465, isSSL false
220 mail.authsmtp.com ESMTP Sendmail 8.14.2/8.14.2/Kp; Thu, 18 Jun 2009 01:35:24 +0100 (BST)
DEBUG SMTP: connected to host "mail.authsmtp.com", port: 465

EHLO jmac.local
250-mail.authsmtp.com Hello sul-pubs-3a.Stanford.EDU [171.66.201.2], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 52428800
250-AUTH CRAM-MD5 DIGEST-MD5 LOGIN PLAIN
250-DELIVERBY
250 HELP
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "52428800"
DEBUG SMTP: Found extension "AUTH", arg "CRAM-MD5 DIGEST-MD5 LOGIN PLAIN"
DEBUG SMTP: Found extension "DELIVERBY", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 
AUTH LOGIN
334 VXNlcm5hjbt7
YWM0MDkwhi==
334 UGFzc3dvjbt7
YXV0aHNtdHAydog3
235 2.0.0 OK Authenticated
DEBUG SMTP: use8bit false
MAIL FROM:<[email protected]>
250 2.1.0 <[email protected]>... Sender ok
RCPT TO:<[email protected]>
250 2.1.5 <[email protected]>... Recipient ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   Jason Thrasher <[email protected]>
DATA
354 Enter mail, end with "." on a line by itself
From: Webmaster <[email protected]>
To: Jason Thrasher <[email protected]>
Message-ID: <[email protected]>
Subject: non-Spring: Hello World
MIME-Version: 1.0
Content-Type: text/plain;charset=UTF-8
Content-Transfer-Encoding: 7bit

Hello World: message body here
.
250 2.0.0 n5I0ZOkD085654 Message accepted for delivery
QUIT
221 2.0.0 mail.authsmtp.com closing connection

ПЛОХОЙ СЛУЧАЙ: вывод журнала при запуске как WAR с отсутствующими заголовками совершенно другой:

Loading javamail.default.providers from jar:file:/Users/jason/.m2/repository/javax/mail/mail/1.4.2/mail-1.4.2.jar!/META-INF/javamail.default.providers
DEBUG: loading new provider protocol=imap, className=com.sun.mail.imap.IMAPStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=imaps, className=com.sun.mail.imap.IMAPSSLStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtp, className=com.sun.mail.smtp.SMTPTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtps, className=com.sun.mail.smtp.SMTPSSLTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3, className=com.sun.mail.pop3.POP3Store, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3s, className=com.sun.mail.pop3.POP3SSLStore, vendor=Sun Microsystems, Inc, version=null
Loading javamail.default.providers from jar:file:/Users/jason/Documents/dev/subscribeatron/software/trunk/web/struts/target/work/webapp/WEB-INF/lib/mail-1.4.2.jar!/META-INF/javamail.default.providers
DEBUG: loading new provider protocol=imap, className=com.sun.mail.imap.IMAPStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=imaps, className=com.sun.mail.imap.IMAPSSLStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtp, className=com.sun.mail.smtp.SMTPTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=smtps, className=com.sun.mail.smtp.SMTPSSLTransport, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3, className=com.sun.mail.pop3.POP3Store, vendor=Sun Microsystems, Inc, version=null
DEBUG: loading new provider protocol=pop3s, className=com.sun.mail.pop3.POP3SSLStore, vendor=Sun Microsystems, Inc, version=null
DEBUG: getProvider() returning provider protocol=smtp; type=javax.mail.Provider$Type@98203f; class=com.sun.mail.smtp.SMTPTransport; vendor=Sun Microsystems, Inc
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "mail.authsmtp.com", port 465, isSSL false
220 mail.authsmtp.com ESMTP Sendmail 8.14.2/8.14.2/Kp; Thu, 18 Jun 2009 01:51:46 +0100 (BST)
DEBUG SMTP: connected to host "mail.authsmtp.com", port: 465

EHLO jmac.local
250-mail.authsmtp.com Hello sul-pubs-3a.Stanford.EDU [171.66.201.2], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 52428800
250-AUTH CRAM-MD5 DIGEST-MD5 LOGIN PLAIN
250-DELIVERBY
250 HELP
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "52428800"
DEBUG SMTP: Found extension "AUTH", arg "CRAM-MD5 DIGEST-MD5 LOGIN PLAIN"
DEBUG SMTP: Found extension "DELIVERBY", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 
AUTH LOGIN
334 VXNlcm5hjbt7
YWM0MDkwhi==
334 UGFzc3dvjbt7
YXV0aHNtdHAydog3
235 2.0.0 OK Authenticated
DEBUG SMTP: use8bit false
MAIL FROM:<[email protected]>
250 2.1.0 <[email protected]>... Sender ok
RCPT TO:<[email protected]>
250 2.1.5 <[email protected]>... Recipient ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   Jason Thrasher <[email protected]>
DATA
354 Enter mail, end with "." on a line by itself

Hello World: message body here
.
250 2.0.0 n5I0pkSc090137 Message accepted for delivery
QUIT
221 2.0.0 mail.authsmtp.com closing connection

Вот настоящий mail.jsp, с которым я тестирую war / non-war.

<%@page import="java.util.*"%>
<%@page import="javax.mail.internet.*"%>
<%@page import="javax.mail.*"%>

<%
    InternetAddress from = new InternetAddress("[email protected]", "Webmaster");
    InternetAddress to = new InternetAddress("[email protected]", "Jason Thrasher");
    String subject = "non-Spring: Hello World";
    String content = "Hello World: message body here";

    final Properties props = new Properties();
    props.setProperty("mail.transport.protocol", "smtp");
    props.setProperty("mail.host", "mail.authsmtp.com");
    props.setProperty("mail.port", "465");
    props.setProperty("mail.username", "myusername");
    props.setProperty("mail.password", "secret");
    props.setProperty("mail.debug", "true");
    props.setProperty("mail.smtp.auth", "true");
    props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.setProperty("mail.smtp.socketFactory.fallback", "false");

    Session mailSession = Session.getDefaultInstance(props);

    Message message = new MimeMessage(mailSession);
    message.setFrom(from);
    message.setRecipient(Message.RecipientType.TO, to);
    message.setSubject(subject);
    message.setContent(content, "text/plain;charset=UTF-8");

    Transport trans = mailSession.getTransport();
    trans.connect(props.getProperty("mail.host"), Integer
            .parseInt(props.getProperty("mail.port")), props
            .getProperty("mail.username"), props
            .getProperty("mail.password"));
    trans.sendMessage(message, message
            .getRecipients(Message.RecipientType.TO));
    trans.close();
%>

email was sent

РЕШЕНИЕ:

Да, проблема заключалась в транзитивных зависимостях Apache CXF 2. Мне пришлось исключить geronimo-javamail_1.4_spec из сборки и просто полагаться на javax mail-1.4.jar.

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>2.2.6</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-javamail_1.4_spec</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Спасибо за все ответы.


person Jason Thrasher    schedule 18.06.2009    source источник
comment
Можете ли вы опубликовать код, использованный для отправки почты?   -  person matt b    schedule 18.06.2009
comment
Привет, Мэтт, см. Мой mail.jsp выше. Полное приложение загружает различные jar-файлы Spring, Struts и Apache, но, поскольку я был настолько сбит с толку в отношении проблемы, я создал этот простой mail.jsp, чтобы протестировать его. Загружается только mail-1.4.2.jar. Я не понимаю, что могло бы сбить с толку отправку электронной почты. Спасибо.   -  person Jason Thrasher    schedule 18.06.2009
comment
Привет, Джейсон, ты нашел решение? У нас немного другой случай, но результат тот же.   -  person Sasha O    schedule 25.09.2009
comment
Не только вокруг причала, в общем, если у вас есть cxf, вам нужно быть осторожным с его зависимостями   -  person pazfernando    schedule 09.10.2015


Ответы (4)


Возможно ли, что когда вы создаете его как WAR, в него втягиваются другие зависимости? Похоже, другие сталкивались с этой проблемой, и причиной была ошибка в geronimo (для получения дополнительной информации см. http://mail-archives.apache.org/mod_mbox/geronimo-user/200902.mbox/%[email protected]%3E).

У нас также есть geronimo-javamail_1.4_spec-1.2, включенный в наш продукт, и в этом пакете есть ошибка с заголовками. Мы исключили это (вместе с geronimo-activate_1.1_spec) из наших зависимостей, и это устранило проблему.

person Jason R. Coombs    schedule 28.08.2009
comment
У меня также была проблема, указанная выше (я использовал Mule, который в конечном итоге привел к Geronimo для некоторых битов). Исключение javamail * _spec определенно должно решить проблему. - person Joshua DeWald; 04.10.2009

Проблема возникает из-за зависимости, поэтому убедитесь, что вы загружаете mail.jar раньше других jar-файлов, содержащих класс javax.mail.Transport. В моем случае виновником был javaee-api-5.0-1.jar

person Vijay Govindarajulu    schedule 29.01.2010

У меня тоже такая же проблема. Я вижу сломанное электронное письмо, когда запускаю TestNG со Spring и целой кучей jar-файлов приложений. Когда я использую простой основной метод java, он работает нормально. Вот отличия классов между запуском этого кода внутри TestNG и PSVM

Это почтовые классы, которые отсутствуют при запуске в TestNG:

-com.sun.mail.smtp.SMTPTransport$Authenticator
-com.sun.mail.smtp.SMTPTransport$DigestMD5Authenticator
-com.sun.mail.smtp.SMTPTransport$LoginAuthenticator
-com.sun.mail.smtp.SMTPTransport$PlainAuthenticator
-com.sun.mail.util.FolderClosedIOException
-com.sun.mail.util.MessageRemovedIOException
-com.sun.mail.util.PropUtil
-javax.mail.FolderClosedException
-javax.mail.MessageRemovedException
-javax.mail.Multipart
-javax.mail.internet.ParameterList$MultiValue
-javax.net.SocketFactory
-javax.net.ssl.SSLException
-javax.net.ssl.SSLPeerUnverifiedException
-javax.net.ssl.SSLSocket

Этот почтовый класс присутствует в TestNG, но не в PSVM

 +javax.mail.internet.CachedDataHandler
person Jonathan Hess    schedule 04.08.2009

В моем случае виновником была некоторая библиотека Amazon, которая заменяла стандартный транспортный механизм:

<dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-java-sdk</artifactId>
       <version>1.3.9</version>
</dependency>

Мне пришлось заставить сеанс использовать стандартный при создании сеанса:

properties.setProperty("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport"); // Fix to prevent Amazon AWS from giving their transport

Я должен упомянуть, что я также реализовал исправления, данные Джейсоном и Виджаем, чтобы исключить библиотеки geronimo.

Возможно, Transport of AMazon SDK использует код geronimo внутри компании? ...

Спасибо!

person will824    schedule 29.11.2012