How do I send an email with attachment?

In this example we create a small program to send email with a file attachment. To send message with attachment we need to create an email with javax.mail.Multipart object which basically will contain the email text message and then add a file to the second block, which both of them is an object of javax.mail.internet.MimeBodyPart. In this example we also use the javax.activation.FileDataSource.

package org.kodejava.mail;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;

public class SendEmailWithAttachment {
    public static void main(String[] args) {
        SendEmailWithAttachment demo = new SendEmailWithAttachment();
        demo.sendEmail();
    }

    public void sendEmail() {
        // Defines the E-Mail information.
        String from = "[email protected]";
        String to = "[email protected]";
        String subject = "Important Message";
        String bodyText = "This is a important message with attachment.";

        // The attachment file name.
        String attachmentName = "data.txt";

        // Creates a Session with the following properties.
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
        Session session = Session.getDefaultInstance(props);

        try {
            InternetAddress fromAddress = new InternetAddress(from);
            InternetAddress toAddress = new InternetAddress(to);

            // Create an Internet mail msg.
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(fromAddress);
            msg.setRecipient(Message.RecipientType.TO, toAddress);
            msg.setSubject(subject);
            msg.setSentDate(new Date());

            // Set the email msg text.
            MimeBodyPart messagePart = new MimeBodyPart();
            messagePart.setText(bodyText);

            // Set the email attachment file
            FileDataSource fileDataSource = new FileDataSource(attachmentName);

            MimeBodyPart attachmentPart = new MimeBodyPart();
            attachmentPart.setDataHandler(new DataHandler(fileDataSource));
            attachmentPart.setFileName(fileDataSource.getName());

            // Create Multipart E-Mail.
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messagePart);
            multipart.addBodyPart(attachmentPart);

            msg.setContent(multipart);

            // Send the msg. Don't forget to set the username and password
            // to authenticate to the mail server.
            Transport.send(msg, "kodejava", "password");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
</dependencies>

Maven CentralMaven Central

Wayan

10 Comments

  1. Hi, I followed your code and its works for me but I want file name as dynamic, for example user uploaded file as attachment. I am using Struts 1.x. Please help me.

    Reply
  2. I am getting this error

    javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 587;
      nested exception is:
        java.net.ConnectException: Connection timed out: connect
        at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1961)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:654)
        at javax.mail.Service.connect(Service.java:366)
        at javax.mail.Service.connect(Service.java:246)
        at javax.mail.Service.connect(Service.java:267)
        at javax.mail.Transport.send0(Transport.java:252)
        at javax.mail.Transport.send(Transport.java:174)
        at com.mail.mailWithAttachment.SendEmailWithAttachment.sendEmail(SendEmailWithAttachment.java:66)
        at com.mail.mailWithAttachment.SendEmailWithAttachment.main(SendEmailWithAttachment.java:14)
    Caused by: java.net.ConnectException: Connection timed out: connect
        at java.net.DualStackPlainSocketImpl.connect0(Native Method)
        at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
        at java.net.PlainSocketImpl.connect(Unknown Source)
        at java.net.SocksSocketImpl.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:321)
        at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237)
        at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1927)
        ... 8 more
    
    Reply
  3. Hi Vivek,

    Check the connection to smtp.gmail.com using telnet command to see if you can connect to it. Use the following command:

    telnet smtp.gmail.com 578
    

    If you can connect you should see something like this

    $ telnet smtp.gmail.com 587
    Trying 74.125.68.109...
    Connected to gmail-smtp-msa.l.google.com.
    Escape character is '^]'.
    220 smtp.gmail.com ESMTP d89sm3363323pfl.7 - gsmtp
    
    Reply
  4. I am unable to execute, throwing exception.

    EXCEPTION:-------------------
    java.lang.NoSuchMethodError: com.sun.mail.util.TraceInputStream.(Ljava/io/InputStream;Lcom/sun/mail/util/MailLogger;)V
    
    Reply
  5. Hi Wayan, Is there any property for compress or zip the file when adding as attachment to the email. Actually I am looking same compression functionality in Apache Camel.

    Reply
  6. Transport.send(msg, "kodejava", "password");

    Its not allowing username and password here. How we can authenticate this one please help me.

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.