Thursday, August 5, 2021

How to Send Email from Java Program with Example

Sending Email from Java program is a common requirement. It doesn't matter whether you are working on core Java application, web application or enterprise Java EE application, you may need to send email to alert support personal with errors, or just send email to users on registration, password reset or asking them to confirm their email after registration. There are many such scenarios, where you need ability to send emails from Java program. In mature applications, you already have a module or library dealing with all king of email functionality and issues e.g. ability to send attachments, images, including signatures and other rich text formatting on emails, but if you have to code something from scratch then Java's Mail API is perfect place.

In this article, we will learn how to send emails from Java application using mail API ( javax.mail ) . Before writing code, you must know some email basics e.g. you need a SMTP (Simple Mail Transfer Protocol) server.

If you are running your Java application in Linux, then you should know that SMTP daemon by default listen on port 25. You can use any mail server to send emails from Java, including public email servers like GMail, Yahoo or any other provider, all you need is their SMTP server details e.g. hostname, port, connection parameters etc.

You can also use SSL, TLS to securely connect and send emails, but in this example we have kept it simple and just focusing on minimum logic to send mail from Java application.

In further articles, we will learn how to send mail using attachments, how to send HTML formatted email, how to attach images in emails, how to use SSL authentication to connect GMail Server and send emails etc. For now, let's understand this simple example of Java Mail API.



Java Code Example to Send Email

In order to send email from Java program you need Java Mail API and Java Activation Framework (JAF), precisely you need mail-1.4.5.jar, smtp-1.4.4.jar, and activation-1.1.jar. You need to download these JAR files and include them in your Classpath to run this program. Alternatively you can use Maven for managing dependencies and can include all dependencies there. Once you have these JAR files covered, just follow below steps to create and send text email from Java.
  1. Create Session object by calling Session.getDefaultInstance(properties), where properties contains all important properties e.g. hostname of SMTP server. 
  2. Create MimeMessage object by passing Session obtained in previous steps. we have to set different properties in this object such as recipient email address, subject, email body, attachments etc.
  3. Use javax.mail.Transport to send the email message by calling static method send(email), where email can be MimeMessage.

Java Program to Send Email using Mail API



Number of properties you pass to create session differs based on the type of SMTP server, for example if SMTP server doesn't require any authentication you can create the Session object with just one property e.g. smtp.mail.host, no need to provide port even because it listen on default port 25.

On the other hand, if you are connecting to an SMTP server that requires TLS or SSL authentication, like GMail's SMTP Host then you will need to provide few more properties like mail.smtp.port=547 for TLS and mail.smtp.port=457 for SSL. 

Here is a complete Java program which connect to default SMTP Server without authentication and send a text email using Java's mail API.

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
* Java Program to send text mail using default SMTP server and 
 * without authentication.
* You need mail.jar, smtp.jar and activation.jar to run this program.
*
* @author Javin Paul
*/
public class EmailSender{

    public static void main(String args[]) {
        String to = "receive@abc.om";            // sender email
        String from = "sender@abc.com";       // receiver email
        String host = "127.0.0.1";                   // mail server host

       Properties properties = System.getProperties();
        properties.setProperty("mail.smtp.host", host);

        Session session = Session.getDefaultInstance(properties); 
        // default session

        try {
            MimeMessage message = new MimeMessage(session);        
            // email message

            message.setFrom(new InternetAddress(from)); 
            // setting header fields
           
            message.addRecipient(Message.RecipientType.TO, 
                               new InternetAddress(to));
            message.setSubject("Test Mail from Java Program"); // subject line

            // actual mail body
            message.setText("You can send mail from Java program by 
                  using mail API, but you need"
                    + "couple of more JAR files e.g. smtp.jar 
                         and activation.jar");

            // Send message
            Transport.send(message);
            System.out.println("Email Sent successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }

}

Output :
You can Compile and run this program to send a simple e-mail from Java program:

$ javac EmailSender.java
$ java EmailSender
Sent email successfully....

As you can see it's very simple to send mails from Java program. Once you have created the MimeMessage object, you need to add recipients which can be TO, CC or BCC. After setting recipients we have setup subject and finally email content itself by message.setText().  If you want to send an e-mail to multiple email ids then the following methods would be used to specify those recipients:

void addRecipients(Message.RecipientType type, Address[] addresses) 
            throws MessagingException

You can add peoples into TO field by using Message.RecipientType.TO, in CC by Message.RecipientType.CC and into BCC by Message.RecipientType.BCC.



Error and Exception

When many Java programmers first start to write programs to send emails, they ran into this error because most of them just think that mail.jar and activation.jar would be enough to send mail form the Java application, which is not true especially if you are sending email via local SMTP server in Linux. If you run this program with just mail.jar and activation.jar in your CLASSPATH, you will most likely get this error.

Exception 1:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: 
  localhost, 25; timeout -1;
  nested exception is:
               java.net.ConnectException: Connection refused: connect
               at com.sun.mail.smtp.SMTPTransport
                 .openServer(SMTPTransport.java:1984)
               at com.sun.mail.smtp.SMTPTransport
                 .protocolConnect(SMTPTransport.java:656)
               at javax.mail.Service.connect(Service.java:345)
               at javax.mail.Service.connect(Service.java:226)
               at javax.mail.Service.connect(Service.java:175)
               at javax.mail.Transport.send0(Transport.java:253)
               at javax.mail.Transport.send(Transport.java:124)
               at Testing.main(Testing.java:62)
Caused by: java.net.ConnectException: Connection refused: connect
               at java.net.DualStackPlainSocketImpl.connect0(Native Method)
               at java.net.DualStackPlainSocketImpl
                .socketConnect(DualStackPlainSocketImpl.java:79)
               at java.net.AbstractPlainSocketImpl
                .doConnect(AbstractPlainSocketImpl.java:339)
               at java.net.AbstractPlainSocketImpl
                  .connectToAddress(AbstractPlainSocketImpl.java:200)
               at java.net.AbstractPlainSocketImpl
                  .connect(AbstractPlainSocketImpl.java:182)
               at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
               at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
               at java.net.Socket.connect(Socket.java:579)
               at java.net.Socket.connect(Socket.java:528)
               at com.sun.mail.util.SocketFetcher
                .createSocket(SocketFetcher.java:301)
               at com.sun.mail.util.SocketFetcher
                 .getSocket(SocketFetcher.java:229)
               at com.sun.mail.smtp.SMTPTransport
                     .openServer(SMTPTransport.java:1950)
               ... 7 more

Solution : Though the solution of this error is very simple, it may direct you in a different direction. Since java.net.ConnectException: Connection refused: connect usually come when either server is down or the port you are connecting is not correct, and this happened to me as well in past. solution is apart from mail-1.4.5.jar, you also need smtp-1.4.4.jar and activation-1.1.jar


Exception 2:
This is another error, called NoClassDefFoundError, which is also related to missing JAR file in Classpath :

Exception in thread "main" java.lang.NoClassDefFoundError:
                javax/mail/MessagingException
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2521)
        at java.lang.Class.getMethod0(Class.java:2764)
        at java.lang.Class.getMethod(Class.java:1653)
        at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: javax.mail.MessagingException
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)


Solution: I managed to resolve my problem, it was because of an incorrect Classpath. Even though I had all three required JAR and Java class files for the program in the same directory and I am running the program from there, Java wasn't able to resolve that. I tried the following command and it worked perfectly for me :

java -cp mail-1.4.5.jar:smtp-1.4.4.jar:activation-1.1.jar:. JavaMailSender
Sent email successfully....
Please notice the current directory denoted by dot (.) at the end of the Classpath argument. Since I was running my program on Linux, I have used a colon as a separator (:) instead of a Windows semicolon (;)

That's all on how to send email from Java program using mail API. You can see it's very simple, apart from three JAR files you don't need much. It's much easy if you use Gradle or Maven for dependency management.  In next couple of tutorials, we will see advanced examples of Java's mail API to send email with attachments, with images and nicely HTML formatted emails to send reports and tables.


16 comments:

  1. Even after release of Java 8, basic functionaltiy like sending mails requires too much configuration and code in Java. I think even UNIX's mail command is better. Ideally you would like config to be specified in one line and content to be another, that's it. By the way, can we send email in Java using Outlook and Gmail at same time?

    ReplyDelete
  2. log prints mail sent successfully,But unable to view the mail in inbox/sentbox.Anyone has the same issue?

    ReplyDelete
  3. Error resolved changed the host to correct one.

    ReplyDelete
  4. Quick note - depending on version, you _might_ not need all three files. On my version (1.6), I downloaded just javax.mail.jar. See http://www.oracle.com/technetwork/java/index-138643.html for more info.
    Also, if you place in ..\Java\jre6\lib\ext no need to add -classpath arg. More info at http://docs.oracle.com/javase/tutorial/ext/basics/index.html (Installed Extensions link).

    ReplyDelete
  5. Hi, I am anish.I am student of GNIIT software engineering and I am making a project of banking application using servlet, jsp.I want some information sent by mail,,,so plz help me step by step in java Mail..

    ReplyDelete
  6. Can we other mail services like yahoo "hotmail" instead of google?

    ReplyDelete
  7. Hi,
    i want know that can we send mail to provided gmailid through JDBC code??

    ReplyDelete
  8. Compiler prints mail sent successfully,however do not to see any message in inbox. What is a problem?

    ReplyDelete
  9. Check the email address and outbox in the host, If your host doesn't have internet address then it may not be able to send.

    ReplyDelete
  10. Hi Need help How to send mail 60 mins before particular time

    ReplyDelete
  11. javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 25;
    nested exception is:
    com.sun.mail.util.SocketConnectException
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638)
    at javax.mail.Service.connect(Service.java:366)
    at javax.mail.Service.connect(Service.java:246)
    at javax.mail.Service.connect(Service.java:195)
    at javax.mail.Transport.send0(Transport.java:254)
    at javax.mail.Transport.send(Transport.java:124)
    at EmailSender.main(EmailSender.java:46)
    Caused by: com.sun.mail.util.SocketConnectException
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:363)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900)
    ... 7 more
    Caused by: java.net.ConnectException: Connection refused: connect
    at java.base/sun.nio.ch.Net.connect0(Native Method)
    at java.base/sun.nio.ch.Net.connect(Net.java:579)
    at java.base/sun.nio.ch.Net.connect(Net.java:568)
    at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
    at java.base/java.net.Socket.connect(Socket.java:633)
    at java.base/java.net.Socket.connect(Socket.java:583)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359)
    ... 9 more

    Is anyone else facing the same issue? Any inputs are appreciated.

    ReplyDelete
  12. Who at this day and age would jump through all these hoops to send an email while not be sure it's configured correctly so that it works properly in all email clients?? Please just go one of the libraries that wrap this low level API in something easier, like Simple Java Mail (https://www.simplejavamail.org/).

    ReplyDelete
  13. How can we set sensitivity labels .
    I tried adding message.setHeader("Sensitivity", "Company-Confidential"); but this is not working

    ReplyDelete
  14. Hello anonymous, which messaging system are you using? The message.setHeader("Sensitivity", "Company-Confidential");, might work in some contexts, but it depends on the messaging system you are using and whether it supports this specific header for setting sensitivity labels or not.

    If you're working with Microsoft 365 (formerly known as Office 365) and want to set sensitivity labels for emails, you should use the Microsoft Graph API, which allows you to manage sensitivity labels for email messages.

    ReplyDelete