views:

1193

answers:

3

I'd like to send mail without bothering with the SMTP-Server which is used for delivery.

So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.

I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.

I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.

An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.

Or does anyone know about other libraries I could use?

+3  A: 

One possible solution: get the MX record on your own and use JavaMail API.

You can get the MX record using the dnsjava project:

Maven2 dependency:

<dependency>
    <groupId>dnsjava</groupId>
    <artifactId>dnsjava</artifactId>
    <version>2.0.1</version>
</dependency>

Method for MX record retrieval:

public static String getMXRecordsForEmailAddress(String eMailAddress) {
    String returnValue = null;

    try {
     String hostName = getHostNameFromEmailAddress(eMailAddress);
     Record[] records = new Lookup(hostName, Type.MX).run();
     if (records == null) { throw new RuntimeException("No MX records found for domain " + hostName + "."); }

     if (log.isTraceEnabled()) {
      // log found entries for debugging purposes
      for (int i = 0; i < records.length; i++) {
       MXRecord mx = (MXRecord) records[i];
       String targetString = mx.getTarget().toString();
       log.trace("MX-Record for '" + hostName + "':" + targetString);
      }
     }

     // return first entry (not the best solution)
     if (records.length > 0) {
      MXRecord mx = (MXRecord) records[0];
      returnValue = mx.getTarget().toString();
     }
    } catch (TextParseException e) {
     throw new RuntimeException(e);
    }

    if (log.isTraceEnabled()) {
     log.trace("Using: " + returnValue);
    }
    return returnValue;
}

private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
    String parts[] = mailAddress.split("@");
    if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
    return parts[1];
}

Sending mail via JavaMail code:

public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
    String smtpServer = getMXRecordsForEmailAddress(toAddress);

    // create session
    Properties props = new Properties();
    props.put("mail.smtp.host", smtpServer);
    Session session = Session.getDefaultInstance(props);

    // create message
    Message msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(fromAddress));
    msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
    msg.setSubject(subject);
    msg.setText(body);

    // send message
    Transport.send(msg);
}
Eduard Wirch
I don't think this would work for the mass case. There are no many administrators that will configure their mail server in open relay mode. You must authenticate yourself to the server..
Lazarin
This isn't a relay scenario. We deliver the mail to the mail server which is responsible for the email address. [email protected] will be delivered to gmail and gmail WILL accept the mail if it is a valid gmail address. This is how the emailing system works.
Eduard Wirch
You're right, you're not describing a relay. But, I think what Lazarin was getting at is that a spam-hardened server will ensure that the sending host is listed in an MX record for the purported sender's domain.
erickson
+2  A: 

Don't.

Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.

Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.

alex
+4  A: 

This is completely the wrong way to handle this.

Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.

You WANT to leverage because they do several things for you.

1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.

2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.

3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.

4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.

Will Hartung