How to Send Email in Java using Gmail SMTP

In this article, we will talk about how to send an email in Java using Gmail’s SMTP server. You don’t need to have extensive knowledge in Java or mail sending technologies. It is focused on beginners and intermediate developers.

Setup 3rd-party Dependencies


If you look for the most popular email library for Java, you will definitely bump into Jakarta Mail. It is the most robust and versatile mail SDK for Java out there. Although you may find yourself lost in a variety of different dependencies and APIs, we will keep it simple and focus on the most straightforward case.

What you need to know is that Jakarta Mail API is a platform-independent and protocol-independent framework for building mail and messaging applications, and Angus Mail is the official implementation of it done by the Eclipse Foundation.

I prefer IntelliJ Idea for Java development. You don’t need the Ultimate version, free Community version works just fine. It also comes with the JDK included. As a build system, I use Gradle as a more modern approach, however you could easily adapt the code to Maven.

Of course, these examples are not bound to any IDE, so you could use your favorite one, or even command-line tools, which is absolutely fine. We will use just the Angus Mail dependency, which should cover our needs.

implementation("org.eclipse.angus:angus-mail:2.0.3")

Sending Plain-text Email


To send plain-text mail mostly you will work with three classes:

  • java.util.Properties – to configure SMTP Server
  • jakarta.mail.Session – to handle authentication and authorization with Gmail
  • jakarta.mail.Message – to build an email itself

Let’s start with the ‘Properties’. All the information could be found in Gmail SMTP documentation. Method that provides properties would look like this:

private static Properties getProperties() {
    Properties prop = new Properties();
    prop.put("mail.smtp.host", "smtp.gmail.com");
    prop.put("mail.smtp.port", "465");
    prop.put("mail.smtp.auth", "true");
    prop.put("mail.smtp.socketFactory.port", "465");
    prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    return prop;
}

Once we have our properties configured, we can proceed with the Session. Here, heavy lifting is done by the Authenticator class, which expects username and password from the Gmail account used to send emails.

private static Session setupSession(Properties prop, String username, String password) {
    Session session = Session.getInstance(prop,
            new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
    return session;
}

The next step is to create a message. Since we are talking about plain-text emails, we will use Message.setText() method. Do not forget to replace <DESTINATION EMAIL> with your recipient.

private static Message createMessage(Session session) throws MessagingException {
    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress("from@gmail.com"));
    message.setRecipients(
            Message.RecipientType.TO,
            InternetAddress.parse("")
    );
    message.setSubject("Test Gmail SMTP");
    message.setText("""
			Dear Sir or Madam,

			This is test email, please do not reply!

			Best regards
			""");

    return message;
}

Finally, we can bring it all together and send our first email.

public static void main(String[] args) {
    final String username = "";
    final String password = "";

    Properties prop = getProperties();
    Session session = setupSession(prop, username, password);

    try {
        Message message = createMessage(session);
        Transport.send(message);
        System.out.println("Email sent successfully!");
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}

Few important notes:

  • Replace <EMAIL> with the sender email.
  • The App Password is a bit more tricky. Google will not accept just a regular password from your Gmail account. First, you need to enable 2-Step-Verification by going to your Google account -> Security -> 2-Step Verification, or just following this link: [Sign in –
  • Google Accounts](https://myaccount.google.com/signinoptions/twosv).
  • Next step is to create an App Password following https://myaccount.google.com/apppasswords.
  • Now you can use the newly created App Password as a replacement for <APP PASSWORD>.

One of the most common issues that you may face is your local network configuration. Firewall or Antivirus software may block outgoing traffic. If you see connection errors, make sure that ports 587 and 465 are open. Additionally, VPN may interfere as well, so worth checking this one too.

Wow! Congratulations on sending your first email in Java with Gmail SMTP Server! But hang on, there’s more. We will have a look at sending HTML emails and emails with embedded images. However, if you are looking for a more comprehensive guide for sending emails with attachments or to multiple recipients, feel free to check this article on how to send emails using Java and Gmail.

Sending HTML Email


What do you say, if we bring more style? We can achieve it with HTML. All the modern email clients support HTML, so let’s leverage this opportunity and play a bit with it. The getProperties() and setupSession() methods stay the same; the one that we need to modify is createMessage(). Instead of setText() now we call setContent(), providing HTML content as a string and content type ”text/html”.

private static Message createHtmlMessage(Session session) throws MessagingException {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress("from@gmail.com"));
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
    message.setSubject("HTML Email");
    String htmlContent = """
        <h1>Awesome email</h1>
        <p>The best paragraph ever.</p>
    """;
    message.setContent(htmlContent, "text/html");
    return message;
}

Of course, you can use more HTML tags to satisfy your requirements.

Sending Email with Embedded Image


After styling an email with HTML, the next most popular question is how to embed an image. The approach is similar to what we did with HTML. We reuse session and properties, and modify the createMessage() method.

There are several options on how to add an image. All of them require the use of `img` tag inside the HTML. However, the ways the resource is linked differ. Let’s look at them in more detail.

Link to an external image

The easiest way is to use a link to an external image. The implementation will look absolutely the same as the previous example, only img tag will be added to the HTML. As a result, we will have something like this:

private static Message createMessageWithImageUrl(Session session) throws MessagingException {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress("from@gmail.com"));
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
    message.setSubject("HTML Email");
    String htmlContent = """
        <h1>Awesome email</h1>
        <img src="https://LINK_TO_THE_IMAGE.png" alt="img"/>
    """;
    message.setContent(htmlContent, "text/html");
    return message;
}

Although the simplicity of this approach is appealing, the downside is that the image is rendered asynchronously because it is not bundled with the email. As a result, if the connection to the server where the image is hosted is weak or broken, your email may fail to load the image. To overcome this issue, you may embed it in the email body, which we will try in the next part.

Embed the Image into the Multipart Body

To insert an image, we need to create a MimeMultipart object, which will consist of two MimeBodyPart objects: HTML and image. Inside the img tag, we reference the image. This is the place where it could be styled, for example, if you want to resize it. The full code of the method is below:

private static Message createMessageWithImage(Session session) throws MessagingException, IOException {
     MimeMessage message = new MimeMessage(session);
     message.setFrom(new InternetAddress("from@gmail.com"));
     message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
     message.setSubject("HTML Email with Image");

     MimeMultipart multipart = new MimeMultipart("related");

  // First part (the html)
     BodyPart htmlBodyPart = new MimeBodyPart();
     String htmlText = """
          <H1>Hello</H1>
          <img src="cid:image">
     """;
     htmlBodyPart.setContent(htmlText, "text/html");
     multipart.addBodyPart(htmlBodyPart);

  // Second part (the image)
     MimeBodyPart imageBodyPart = new MimeBodyPart();
     imageBodyPart.attachFile(PATH_TO_A_LOCAL_IMAGE);
     imageBodyPart.setContentID("<image>");

  // Add image to the multipart
     multipart.addBodyPart(imageBodyPart);

  // Put everything together
     message.setContent(multipart);

     return message;
}

Make sure to replace PATH_TO_A_LOCAL_IMAGE with the actual path to the image that you want to send.

Gmail SMTP Limitations


The last topic that I would like to cover in this article is Gmail SMTP Server limitations. Google tries to maintain a fair policy for all the users considering that their service can be used for free. Additionally, they ensure that connection and access to the account are secure. Here are the main points to keep in mind:

  • Connection: Your application should establish a secure connection to the SMTP server using either SSL (port 465) or TLS (port 587) protocol.
  • Authentication: You are required to have a Google account to be able to send emails. As described earlier, it should be configured with 2-Step Verification and an App Password.
  • Sending limit: If you use your personal Google Account you are limited to around 100-150 emails per day. With Google Workspace, the number goes up to 2000.
  • Recipients limit: For one email, there is a limit of 500 recipients, including to, cc, and bcc. The limits for Google Workspace accounts may vary.
  • Attachment size limit: The size of all attachments should be up to 25MB.

Don’t forget that policies change over time, so you may need to double check before your app goes live.

Wrapping up

In this article, we covered different options to send an email in Java using Gmail SMTP. The easiest way is a plain-text email. However, with a small adjustment, you can send an HTML with much more capabilities to style and structure your message. Additionally, we covered embedding images, both internal and external. In the end, I added some notes on Gmail SMTP limitations.

Whenever this journey takes you, stay tuned and keep learning 🙂