Erro ao enviar email com a API JavaMail

E ai galera…

Estou com o seguinte problema, tenho uma aplicação que necessita enviar emails, tenho uma classe responsável pelo envio
mais quando eu tento enviar os emails aparece a seguinte exception.

[code]DEBUG SMTP: Sending failed because of invalid destination addresses
RSET
250 Reset state
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 554 Relay rejected for policy reasons.
;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 554 Relay rejected for policy reasons.

at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1835)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1098)
at javax.mail.Transport.send0(Transport.java:195)
at javax.mail.Transport.send(Transport.java:124)
at br.com.amazonas.sistecam.email.MailJavaSender.senderMail(MailJavaSender.java:139)
at br.com.amazonas.sistecam.email.EnviarEmail.enviarEmails(EnviarEmail.java:66)
at br.com.amazonas.sistecam.controllers.VisitaController.finalizavisita(VisitaController.java:359)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:89)
at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.util.hibernate.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:48)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 554 Relay rejected for policy reasons.
;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 554 Relay rejected for policy reasons.

at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1733)
... 58 more

Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 554 Relay rejected for policy reasons.

... 59 more

QUIT[/code]

Posta o trecho do código onde ocorre o erro!

[code]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */

package br.com.amazonas.sistecam.email;

import java.io.IOException;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Multipart;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Properties;
import javax.mail.util.ByteArrayDataSource;

/**
*

  • @author cassio
    */

public class MailJavaSender {

//cria as propriedades necessárias para o envio de email
public void senderMail(final MailJava mail) throws
     UnsupportedEncodingException, MessagingException, IOException {

    Properties props = new Properties();
    //define o protocolo
    props.setProperty("mail.transport.protocol", "smtp");
    //define o servidor de email
    props.setProperty("mail.host", mail.getSmtpHostMail());
    //indica se o servidor necessita de autenticação(TRUE,FALSE)
    props.setProperty("mail.smtp.auth", mail.getSmtpAuth());
    //indica ao servidor que ele está recebendo uma conexão segura
    props.setProperty("mail.smtp.starttls.enable", mail.getSmtpStarttls());
    //define a porta do servidor
    props.setProperty("mail.smtp.port", mail.getSmtpPortMail());
    //define o charset, no caso de html é necessário
    props.setProperty("mail.mime.charset", mail.getCharsetMail());

    //classe anonima que realiza a autenticação
    //do usuario no servidor de email.
    Authenticator auth = new Authenticator() {
        @Override
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(
                               mail.getUserMail(), mail.getPassMail()
             );
        }
    };

    // Cria a sessao passando as propriedades e a autenticação
    Session session = Session.getDefaultInstance(props, auth);
    // Gera um log no console referente ao processo de envio
    session.setDebug(true);

    //cria a mensagem setando o remetente e seus destinatários
    Message msg = new MimeMessage(session);
    //aqui seta o remetente
    msg.setFrom(new InternetAddress(
                      mail.getUserMail(), mail.getFromNameMail())
     );
    //aqui seta os destinatarios da mensagem de acordo com o Map de String
    //TO - para
    //CC - com cópia
    //BCC - com cópia oculta

    boolean first = true;
    for (Map.Entry<String, String> map : mail.getToMailsUsers().entrySet()) {
        if (first) {
            //setamos o 1° destinatario
            msg.addRecipient(Message.RecipientType.TO,
                      new InternetAddress(map.getKey(), map.getValue())
             );
            first = false;
        } else {
            //setamos os demais destinatarios
            msg.addRecipient(Message.RecipientType.BCC,
                      new InternetAddress(map.getKey(), map.getValue())
             );
        }
    }
    msg.addRecipient(Message.RecipientType.BCC, new InternetAddress("cassiothadeu@amazonas.com.br", "Cassio"));

    // Adiciona um Assunto a Mensagem
    msg.setSubject(mail.getSubjectMail());

    // Cria o objeto que recebe o texto do corpo do email
    //Corpo que pode ser um texto ou html
    MimeBodyPart textPart = new MimeBodyPart();
    textPart.setContent(mail.getBodyMail(), mail.getTypeTextMail());

    // Monta a mensagem SMTP  inserindo o conteudo, texto e anexos
    Multipart mps = new MimeMultipart();
    if(!mail.getFileMails().isEmpty()){
        for (int index = 0; index < mail.getFileMails().size(); index++) {

            // Cria um novo objeto para cada arquivo, e anexa o arquivo
            MimeBodyPart attachFilePart = new MimeBodyPart();
            FileDataSource fds =   new FileDataSource(
                 mail.getFileMails().get(index)
             );
            attachFilePart.setDataHandler(new DataHandler(fds));
            attachFilePart.setFileName(fds.getName());

            //adiciona os anexos da mensagem
            mps.addBodyPart(attachFilePart, index);

        }
    }
    
    //cria um novo objeto contendo o stream da memoria
    MimeBodyPart attachStream = new MimeBodyPart();
    attachStream.setDataHandler(new DataHandler(new ByteArrayDataSource(mail.getAttachStream().toByteArray(), mail.getCharsetAttachStream())));
    attachStream.setFileName(mail.getTitleAttach());
    
    //adiciona o anexo stream na mensagem
    mps.addBodyPart(attachStream);
    
    //adiciona o corpo texto da mensagem
    mps.addBodyPart(textPart);

    //adiciona a mensagem o conteúdo texto e anexo
    msg.setContent(mps);

    // Envia a Mensagem
    Transport.send(msg);
}

}[/code]

no log aparece o seguinte

DEBUG SMTP: Valid Unsent Addresses
DEBUG SMTP: titton@amazonas.com.br
DEBUG SMTP: bruxel@amazonas.com.br
DEBUG SMTP: henrique@amazonas.com.br
DEBUG SMTP: Cassio cassiothadeu@amazonas.com.br
DEBUG SMTP: Invalid Addresses
DEBUG SMTP: ribeiroqm@valear.com.br
DEBUG SMTP: mauriciophi@uol.com.br
DEBUG SMTP: Sending failed because of invalid destination addresses
RSET

Aparentemente o servidor de mail não deixa enviar para outros domínios que não esse amazonas.com.br.

Mais nosso servidor não possui nenhuma restrição de envio de email.

Pega todos os emails no map e tenta enviar um a um na mão, com o mesmo servidor smtp.
Seria bom também colocar no log qual email que está tendo problema.

o Log esta somente no catalina.out do tomcat

como eu poderia criar um arquivo para armazenar esses logs?

[quote=ksio_thadeu]o Log esta somente no catalina.out do tomcat

como eu poderia criar um arquivo para armazenar esses logs?[/quote]
Usa o log4J.
Ou bota um System.out aí e olha no console, pra fazer um teste rapido…mas é sempre bom aprender e implementar um decente sistema de log. Fica muito mais fácil testar a acompanhar a aplicação.

eu possuo o seguinte arquivo de configuracao do log4j.xml

[code]<?xml version="1.0" encoding="UTF-8" ?>

<log4j:configuration xmlns:log4j=“http://jakarta.apache.org/log4j/”>

    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
            <layout class="org.apache.log4j.PatternLayout">
                    <param name="ConversionPattern" 
                            value="%d{HH:mm:ss,SSS} %5p [%-20c{1}] %m%n"/>
            </layout>
    </appender>

    <category name="org.vraptor">
            <priority value="INFO" />
            <appender-ref ref="stdout" />
    </category>

    <category name="com.thoughtworks">
            <priority value="INFO" />
            <appender-ref ref="stdout" />
    </category>
            
    <category name="br.com.caelum.vraptor">
            <priority value="DEBUG" />
            <appender-ref ref="stdout" />
    </category>
    
    <category name="org.springframework">
            <priority value="INFO" />
            <appender-ref ref="stdout" />
    </category>

</log4j:configuration>
[/code]

mais nao sei como criar um arquivo para armazenar os logs e nao no catalina.out

Voce tem que criar um File appender e mapear o pacote “br.com.amazonas.sistecam.email” para este appender.

&lt;appender name="email" class="org.apache.log4j.RollingFileAppender"&gt;
    &lt;param name="File"   value="email.teste_email.log" /&gt;
    &lt;param name="Append" value="true" /&gt;
    &lt;param name="MaxFileSize" value="3000KB" /&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d{DATE} %-5p %-15c{1}: %m%n"/&gt;
    &lt;/layout&gt;
 &lt;/appender&gt;

&lt;category name="br.com.amazonas.sistecam.email"&gt;  
    &lt;priority value="INFO" /&gt;  
    &lt;appender-ref ref="email" /&gt;  
&lt;/category&gt;

mais esse codigo eu tenho que colocar dentro do arquivo log4j.xml??

[quote=ksio_thadeu]mais esse codigo eu tenho que colocar dentro do arquivo log4j.xml??
[/quote]sim

Se você estiver usando Eclipse ou Netbeans adiciona a biblioteca slf4j www.slf4j.org ao seu IDE e você vai poder acompanhar as mensagem em tempo de execução.

comforme a configuração do log4j acima o arquivo esta sendo criado mais em branco