2009-06-18 14 views
10

Qualcuno ha visto JavaMail che non invia MimeMessages appropriati a un server SMTP, a seconda di come è iniziata la JVM? Alla fine della giornata, non posso inviare messaggi SMTP JavaMail con Subject: o From: fields, e sembra che manchino altre intestazioni, solo quando si esegue l'app come guerra.JavaMail non invia Soggetto o Da sotto molo: run-war

Il progetto web è costruito con Maven e sto testando l'invio di JavaMail utilizzando un browser e un semplice mail.jsp per eseguire il debug e vedere un comportamento diverso quando si lancia l'applicazione con:

1) pontile mvn: gestito (posta invia bene, con una corretta Soggetto e dai campi)

2) pontile mvn: run-guerra (posta elettronica invia bene, ma Soggetto mancante, Da, e altri campi)

ho meticolosamente eseguire diff sull'output di debug Maven (-x) (-X) e ci sono zero differenze nelle dipendenze di runtime tra i due. Ho anche confrontato le proprietà del sistema e sono identiche. Qualcos'altro sta accadendo sul molo: caso run-war che cambia il modo in cui si comporta JavaMail. Quali altre pietre devono essere girate?

Stranamente, ho provato un debugger in entrambe le situazioni e ho scoperto che l'istanza javax.mail.internet.MimeMessage viene creata in modo diverso. La webapp utilizza Spring per inviare e-mail prelevate da una coda Apache ActiveMQ. Quando si esegue l'app come mvn jetty:run, la variabile MimeMessage.contentStream viene utilizzata per il contenuto del messaggio. Quando viene eseguito come mvn jetty:run-war, la variabile MimeMessage.content viene utilizzata per il contenuto del messaggio e il contenuto = ASCIIUtility.getBytes (is); La chiamata rimuove tutti i dati dell'intestazione dal contenuto analizzato. Poiché questo sembrava molto strano, e il debug di Spring/ActiveMQ è un'immersione profonda, ho creato un test semplificato senza alcuna infrastruttura: solo un JSP che utilizza mail-1.4.2.jar, ma mancano le stesse intestazioni.

Inoltre, queste intestazioni mancano quando si esegue il file WAR in Tomcat 5.5.27. Tomcat si comporta proprio come Jetty quando esegue la WAR, con le stesse intestazioni mancanti.

Con il debug JavaMail attivato, vedo chiaramente diversi output.

buon caso: nel molo: run (non-WAR) l'output di log è:

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 

brutto caso: l'uscita di registro durante l'esecuzione come WAR, con le intestazioni mancanti, è ben diversa:

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; [email protected]; 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 

Ecco l'effettivo mail.jsp con cui sto testando guerra/non guerra.

<%@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 

SOLUZIONE:

Sì, il problema era dipendenze transitive su Apache CXF 2. ho dovuto escludere geronimo-javamail_1.4_spec dalla costruzione, e fare affidamento solo sulla posta 1.4.jar di javax.

<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> 

Grazie per tutte le risposte.

+0

puoi pubblicare il codice utilizzato per inviare effettivamente la posta? –

+0

Ciao Matt, certo, vedi il mio mail.jsp sopra. L'app completa carica vari Spring, Struts e Apache jars, ma dato che ero così confuso sul problema, ho creato questo semplice mail.jsp, per testarlo con. Viene caricato solo mail-1.4.2.jar. Sono in perdita per quanto riguarda l'invio di e-mail. Grazie. –

+0

Ciao Jason, hai trovato la soluzione? Abbiamo un caso leggermente diverso ma il risultato è lo stesso. –

risposta

9

È possibile che, quando lo costruisci come WAR, vengano caricate altre dipendenze? Sembra che altri abbiano riscontrato questo problema e la causa era un bug in geronimo (per ulteriori informazioni, vedere http://mail-archives.apache.org/mod_mbox/geronimo-user/200902.mbox/%[email protected]%3E).

Abbiamo anche geronimo-javamail_1.4_spec-1.2 incluso nel nostro prodotto e quel pacchetto ha un bug con le intestazioni. Abbiamo escluso questo (insieme a geronimo-activation_1.1_spec) dalle nostre dipendenze e ha corretto il problema.

+1

Ho anche avuto il problema sopra (stava usando Mule, che ha finito per portare in Geronimo alcuni bit). Escludendo javamail * _spec è necessario risolvere il problema. –

+0

Hai ragione, era geronimo. Grazie per l'aiuto. –

+0

Si salva la vita! – seanhodges

0

Anche io sto avendo lo stesso problema. Vedo l'email spezzata quando corro in TestNG con Spring e un sacco di barattoli di applicazioni. Quando corro in un semplice metodo main java, funziona perfettamente.Qui ci sono le differenze di classe tra quando si esegue questo codice all'interno TestNG vs PSVM

Queste sono le classi di posta elettronica che sono assenti quando corro in TestNG:

classe
-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 

Questa posta è presente in TestNG, ma non PSVM

+javax.mail.internet.CachedDataHandler 
2

È la dipendenza che crea questo problema, assicurati di caricare mail.jar prima di altri jar che contengono la classe javax.mail.Transport. Nel mio caso il colpevole era JavaEE-api-5.0-1.jar

0

Nel mio caso, il colpevole reale era qualche libreria di Amazon che è stato sostituendo il meccanismo di trasporto di serie:

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

ho dovuto forzare la sessione di usare quello standard di nuovo durante la creazione della sessione:

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

devo dire che ho anche implementato le correzioni fornite dal Jason e Vijay al fine di escludere le librerie Geronimo.

Forse il trasporto di Amazon SDK sta usando il codice Geronimo internamente? ...

Grazie!