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 = "kodejava@gmail.com";
        String to = "kodejava@gmail.com";
        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 Central Maven 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

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