Getting invalid address using javax.mail when addresses are specified

I am using javax.mail system and have problems with "Invalid address" exceptions. Here's the basics of the code:

// Get system properties Properties props = System.getProperties(); // Setup mail server props.put("mail.smtp.host", m_sending_host); // Get session Session session = Session.getDefaultInstance(props, new Authenticator(){ @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(m_sending_user, m_sending_pass); } }); // Define message MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(m_sending_from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(vcea.get(i).emailaddr)); message.setSubject( replaceEnvVars(subject) ); message.setText(replaceEnvVars(body)); // Send message try { Transport.send(message); } catch (Exception e){ Log.Error("Error sending e-mail to addr (%s): %s", vcea.get(i).emailaddr, e.getLocalizedMessage() ); } 

The problem is that the above code really works. But for some email addresses that I know are valid (because I can send them through a standard email client), the code above will throw an "Invalid Address" exception when trying to send.

Any hints or tips are appreciated.

- Update: authentication problem.

Ok, here I discovered that this is happening. Upon receipt of the email, the code above sets authentication correctly and the Authenticator.getPasswordAuthentication () callback is actually called.

Not so when sending emails. You have to do a little more. Add this:

  // Setup mail server props.put("mail.smtp.host", m_sending_host); props.put("mail.smtp.auth", "true"); 

which will force the javax.mail API to authenticate the login. And then use the actual transport instance instead of the static .send () method:

  Transport t = session.getTransport(m_sending_protocol); t.connect(m_sending_user, m_sending_pass); 

...

  // Send message try { t.sendMessage(message, message.getAllRecipients()); } catch (Exception e){ 

Without forced authentication, the mail server saw me as an unauthorized relay and simply shut me down. The difference between the addresses that "worked" and not the addresses that were not the same were those that "worked" were local to the mail server. Therefore, he simply accepted them. But for any non-local "relay" addresses, it would reject the message because my authentication information was not provided by the javax.mail API when I thought it would be.

Thanks for the tips to encourage me to also look at the mail server side.

+4
source share
5 answers

- Update: authentication problem.

Ok, here I discovered that this is happening. Upon receipt of the email, the code above sets authentication correctly and the Authenticator.getPasswordAuthentication () callback is actually called.

Not so when sending emails. You have to do a little more. Add this:

 // Setup mail server props.put("mail.smtp.host", m_sending_host); props.put("mail.smtp.auth", "true"); 

which will force the javax.mail API to authenticate the login. And then use the actual transport instance instead of the static .send () method:

 Transport t = session.getTransport(m_sending_protocol); t.connect(m_sending_user, m_sending_pass); 

...

  // Send message try { t.sendMessage(message, message.getAllRecipients()); } catch (Exception e){ 

Without forced authentication, the mail server saw me as an unauthorized relay and simply shut me down. The difference between the addresses that "worked" and not the addresses that were not the same were those that "worked" were local to the mail server. Therefore, he simply accepted them. But for any non-local "relay" addresses, it would reject the message because my authentication information was not provided by the javax.mail API when I thought it would be.

Thanks for the tips to encourage me to also look at the mail server side.

+5
source

I would modify the call in InternetAddress to use a β€œstrict” interpretation and see if you had any additional errors at the addresses you encountered.

 message.addRecipient(Message.RecipientType.TO, new InternetAddress(vcea.get(i).emailaddr, true )); // ^^^^ turns on strict interpretation 

Javadoc for InternetAddress Designer

If this fails, it will throw an AddressException that has a method called getPos() that returns the failure position ( Javadoc )

+2
source

A good tip for those who use ssl encryption in the smtp configuration is to enable it by specifying the mail.smtp.ssl.enable property, as shown below:

 props.put("mail.smtp.ssl.enable", "true"); 

Otherwise, it can lead to similar problems described above.

+1
source

Try the following:

 String to=" stackoverflow@so.com "; String cc=" one@mail.com , two@mail.com "; //The separator ',' works good message.setRecipients(Message.RecipientType.TO,new InternetAddress[] { new InternetAddress(to) }); // This is only one mail InternetAddress[] addr = parseAddressList(cc); //Here add all the rest of the mails message.setRecipients(Message.RecipientType.CC,addr); 

Sorry for my English. This is not good.

0
source

It seems to me that this is a problem that occurred in my work. If the displayed code is parallel, using System.getProperties directly can be a problem, because the host value that you impose on them can be overwritten with the following query, while maintaining the user and password from the rewritten host.

In our case, we decided that using the clone of the hash table System.getProperties ()

Hope this helps (this problem is really hard to track).

0
source

All Articles