Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send email with gmail using java

Tags:

java

gmail

As title says, I would like to send emails with my gmail account writing some java code. I have found many code examples, but none of them is working for me

I was looking a this one: How can I send an email by Java application using GMail, Yahoo, or Hotmail?

I have tried the code posted as answer, but I get this exception:

javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1717)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1704)
    at com.sun.mail.smtp.SMTPTransport.ehlo(SMTPTransport.java:1088)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:468)
    at javax.mail.Service.connect(Service.java:291)
    at javax.mail.Service.connect(Service.java:172)
...

The code is this:

public class GmailTest {
   
    private static String USER_NAME = "*****";  // GMail user name (just the part before "@gmail.com")
    private static String PASSWORD = "********"; // GMail password
    private static String RECIPIENT = "[email protected]";

    public static void main(String[] args) {
        String from = USER_NAME;
        String pass = PASSWORD;
        String[] to = { RECIPIENT }; // list of recipient email addresses
        String subject = "Java send mail example";
        String body = "Welcome to JavaMail!";

        sendFromGMail(from, pass, to, subject, body);
    }

    private static void sendFromGMail(String from, String pass, String[] to, String subject, String body) {
        Properties props = System.getProperties();
        String host = "smtp.gmail.com";
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", pass);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(props);
        MimeMessage message = new MimeMessage(session);

        try {
            message.setFrom(new InternetAddress(from));
            InternetAddress[] toAddress = new InternetAddress[to.length];

            // To get the array of addresses
            for( int i = 0; i < to.length; i++ ) {
                toAddress[i] = new InternetAddress(to[i]);
            }

            for( int i = 0; i < toAddress.length; i++) {
                message.addRecipient(Message.RecipientType.TO, toAddress[i]);
            }

            message.setSubject(subject);
            message.setText(body);
            Transport transport = session.getTransport("smtp");
            transport.connect(host, from, pass);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Should this work in 2022 or did something change? Why am I getting that exception?

like image 986
Maik Avatar asked Sep 03 '26 15:09

Maik


2 Answers

    public class EmailService {

    private String username;
    private String password;

    private final Properties prop;
public EmailService(String host, int port, String username, String password) {
            prop = new Properties();
            prop.put("mail.smtp.auth", true);
            prop.put("mail.smtp.starttls.enable", "true");
            prop.put("mail.smtp.host", host);
            prop.put("mail.smtp.port", port);
            prop.put("mail.smtp.ssl.trust", host);
    
            this.username = username;
            this.password = password;
        }
    
        public void sendMail(String from,String to,String subject, String msg) throws Exception {
    
            Session session = Session.getInstance(prop, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
    
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            message.setSubject(subject);
    
            MimeBodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
    
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBodyPart);
    
            message.setContent(multipart);
    
            Transport.send(message);
}
        }

and then call the function like so:

new EmailService("smtp.gmail.com", 587, "<emailID>", "<pass(not the actual gmail-account password if you're using gmail for this>")
                    .sendMail("<emailID>",
                            toemail,
                            "<title>",
                            "<body>);

However, that's only half the solution. Since they discontinued the Less Secure App Access feature on gmail accounts, you should access your gmail account through a different way now.

You must enable 2FA on that gmail account, and add an entry to App passwords under your google account. After that, the password you provide in the above function would be the 'App password' that you got from the gmail account(not the actual gmail account password, this one is auto-generated I believe).

enter image description here

I am unaware of any other email service that offers smtp email feature for free nowadays. They all require you to pay in someway,except for gmail(Correct me if I'm wrong)

like image 72
hidden_machine Avatar answered Sep 06 '26 06:09

hidden_machine


First of all, you cannot use password while sending email via Gmail. You need to generate app-specific password for this.

To enable app-specific password follow below steps.

Step 1: Enable 2FA. To enable 2FA, please click here.

Step 2: Create an app-specific password. To create one, please click here.

Click on the highlighted option from the "Select app" dropdown. Click Generate. It will generate 16 digits password and appear only once. Copy somewhere for future use.

enter image description here

In application.properties file add below lines for email configurations

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=YOUR GMAIL ID
spring.mail.password=APP-SPECIFIC PASSWORD
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

The maven dependency can also be added by modifying your project’s pom.xml file to include the following

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

If you need HTML email, you can use MimeMessage class for this purpose.

The service file to send the email is as following. This will create HTML emails for you.

package com.comp.service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import com.comp.serviceIntf.EmailService;

@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    private JavaMailSender mailSender;
    
    @Override
    public void sendEmail(String to, String name, String userid, String password) throws MessagingException
    {
        String htmlContent = "Hi %s, <br /><br />Welcome to <b>MyCompany</b>. <br />Your UserID is: <b>%s</b> and Password is: <b>%s</b><br /><h5>This is system generated password. You can change it anytime after login.</h5><h5>Please do not share this credential with anybody else.</h5><br />With regards,<br />MyCompany";
        htmlContent = String.format(htmlContent, name, userid, password);
        
        String subject = "Welcome %s (%s) on successful registration";
        subject = String.format(subject, name, userid);
        
        
        MimeMessage message = mailSender.createMimeMessage();
        message.setRecipients(MimeMessage.RecipientType.TO, to);
        message.setSubject(subject);
        message.setContent(htmlContent, "text/html; charset=utf-8");
        mailSender.send(message);
    }
}

If you do not need HTML email, you can use SimpleMailMessage class for this purpose.

SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(body);

mailSender.send(message);

Note: I am unaware of any other email like yahoo, outlook etc. This discussion is purely from Gmail point of view.

like image 24
Kuntal Ghosh Avatar answered Sep 06 '26 06:09

Kuntal Ghosh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!