views:

1051

answers:

3

I need to send simple html-message with JavaMail. And when I tried to find some nice examples with explanations in the Internet, each next example made me more angry and angry.

All those silly examples contain copied and pasted Java code which differs only in comments and a nice disclaimer that first you should config your smtp and pop3 server.

I understand that nobody wants to make an advertise for some concrete products but configuring the server is imho the hardest part. So, can anyone give me some really useful information (without java code) about configuring concrete server (Kerio, for example, or any other one)?

What I have now is the next exception:

250 2.0.0 Reset state
javax.mail.SendFailedException: Invalid Addresses;
  nested exception is:
    com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Relaying to <[email protected]> denied (authentication required)

UPD. Simple reformulation of all previous text is: imagine that you have Windows, jdk, and nothing else. And you want to make java program and run it on your machine. And this program should send "Hello world!" to your gmail account. List your steps.

UPD2. Here is the code:

Properties props = new Properties ();
props.setProperty ("mail.transport.protocol", "smtp");
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty ("mail.user", "[email protected]");
props.setProperty ("mail.password", "password_from_email_above"); 

Session mailSession = Session.getDefaultInstance (props, null);
mailSession.setDebug (true);
Transport transport = mailSession.getTransport ();

MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML  mail with images");
message.setFrom (new InternetAddress ("[email protected]"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO,
        new InternetAddress ("[email protected]"));

transport.connect ();
transport.sendMessage (message,
        message.getRecipients (Message.RecipientType.TO));

And exception is:

RSET
250 2.1.5 Flushed 3sm23455365fge.10
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. 3sm23455365fge.10
    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1829)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1368)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:886)
    at com.teamdev.imgmail.MailSender.main(MailSender.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...
+4  A: 

If you're looking for a tutorial to configure an SMTP server, you shouldn't be looking for JavaMail. Simply look for a tutorial on your server of choice (Kerio, for example ... or Exim, SendMail, Apache James, Postfix) or ask on Serverfault. Any SMTP-compliant server will play nicely with JavaMail.

Alternatively, you may even use any "standard" mail provider's infrastructure. For example, I use a Google Apps account along with Google's SMTP infrastructure to send mail from our Java applications. Using a Gmail account is a good starting point anyway if you don't want to setup your own SMTP server in order to simply testdrive JavaMail.

As a last option, you might even lookup the MX Records for a domain and deliver your mails directly to the SMTP server of the recipient. There are some common gotchas to workaround tough.

As a last point, you'll have to look into how to avoid that your mails be filtered as spam - which is a huge topic itself. Here it helps to rely on standard providers that will deal with some of the issues you might encounter when hosting your own server.

Btw: Regarding the error message you posted: the SMTP server is denying relaying of messages. This is if your SMTP server (thinks that it) is running on example.com and you're sending as [email protected] to [email protected], you're asking the SMTP server to act as a relay. This was common practice several years ago, until it was - you guessed it - abused by spammers. Since those days, postmasters are encouraged to deny relaying. You have two choices: authenticate before sending mail or send to accounts hosted at your server only (i.e. on example.com, e.g. [email protected]).

Edit:

Here is some code to get you started with authenticationg (works with Gmail accounts but should do for your own server as well)

private Session createSmtpSession() {
  final Properties props = new Properties();
  props.setProperty("mail.smtp.host", "smtp.gmail.com");
  props.setProperty("mail.smtp.auth", "true");
  props.setProperty("mail.smtp.port", "" + 587);
  props.setProperty("mail.smtp.starttls.enable", "true");
  // props.setProperty("mail.debug", "true");

  return Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication("[email protected]", "mypassword");
    }
  });
}
sfussenegger
+1  A: 

I can see part of your problem. It's adequately explained in the error message.

The SMTP server you are sending your mail to (i.e. one of the addresses you've configured in your JavaMail configuration) is refusing to forward mail to [email protected]. Looks like a configuration issue in your SMTP server. As sfussenegger indicated, it has nothing to do with javamail.

So you're not debugging on all fronts at the same time, it might be a good idea to try addressing your SMTP server from a known working SMTP client. Thunderbird would do fine, for example. If you can send mail through it from Thunderbird, there should be little problem from JavaMail.


Update:

The correct address for Google's SMTP server is: smtp.gmail.com . Is this the server you have configured in JavaMail? Can you show us the matching error message?

Carl Smotricz
A: 

This should work:

import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Emailer {

    public static void main(String[] args) {

     String hostname = args[0];
     final String userName = args[1];
     final String passWord = args[2];
     String toEmail = args[3];
     String fromEmail = args[4];
     String subject = args[5];
     String body = "";
     // add rest of args as one body text for convenience
     for (int i = 6; i < args.length; i++) {
      body += args[i] + " ";
     }

     Properties props = System.getProperties();
     props.put("mail.smtp.host", hostname);

     Session session = Session.getInstance(props, new Authenticator() {
      @Override
      protected PasswordAuthentication getPasswordAuthentication() {
       return new PasswordAuthentication(userName, passWord);
      }
     });

     MimeMessage message = new MimeMessage(session);
     try {
      message.setFrom(new InternetAddress(fromEmail));
      message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
      message.setSubject(subject);
      message.setText(body);
      Transport.send(message);

     } catch (MessagingException e) {
      System.out.println("Cannot send email " + e);
     }
    }
}

You need to put the JavaMail mail.jar on your classpath for the javax.mail dependencies. I'm not sure if Google lets you send email like you want to. How about trying another email provider, like your ISP's?

Adriaan Koster
Google lets me send mail wherever I want (including via the API) so long as I specify my correct return address (or one of the ones I've registered with Google).
Carl Smotricz