I have an automated java mail application that sends automated mail to users when some important update occur in our database. It was working fine. However it started to give me errors and I realized that it's not working.
The error says:
"Please log in via your web browser and then try again.
Learn more at https://support.google.com/mail/bin/answer.py?answer=78754 l10sm7526045oev.7 - gsmtp"
The java mail application that I write is huge and contains some confidential values(password etc.), I decided to write a sample demo to show you what's going on. It gives me the same error. Please assume that javax.MAIL API has been imported to the project. Here is what I have:
public class MailDemo {
public static void main(String[] args) {
final String userName = "dummyEmail#gmail.com";
final String password = "dummyPassword";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");//Smtp server address
props.put("mail.smtp.port", "587");//port for the smtp server
Session session = Session.getInstance(props, new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(userName, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("dummyEmail#gmail.com"));//from email address
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("dummyEmail#gmail.com"));//to email address
message.setSubject("My first Email");//Subject of the mail
message.setContent("<h1>This is a test email</h1>", "text/html; charset=utf-8");//Content of the mail
Transport.send(message);//send the message
System.out.println("Email Stiation:Done!");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Well, i found the problem. Actually the codes are correct. It's gmail. it blocks the sign in attempts.I think that gmail thinks the attempts are not real.
Related
My Java Windows app needs to send email and allow the user to specify his/her email account credentials: host, port, username, password. It works when I use my credentials for an account at my hosting service, but not so well when using a Gmail account, as my prospective users might want to do. The problem is Gmail insists on an "App password." So, I follow the Google instructions and create a 16-character App password which Google says has to be used one time only. However, I find that the App password MUST be used for subsequent runs.
Here's a sample program that demonstrates the problem. It will fail if I use that actual password for the Gmail account. It will work after I've created an App/device specific password (16 characters) and used it as the password, as it should. But, I have to use that 16-character password thereafter as well. What am I missing?
public class SendEmailTLS {
// Example 1 from https://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
public static void main(String[] args) {
final String username = "me123#gmail.com";
final String password = "mypassword";
Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.starttls.enable", "true"); //TLS
Session session = Session.getInstance(prop,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("me123#gmail.com"));
message.setRecipients(
Message.RecipientType.TO,
InternetAddress.parse("you456#hotmail.com")
);
message.setSubject("Testing Gmail TLS");
message.setText("Dear sir,"
+ "\n\n I'm testing TLS,using port 587");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
I want to add that I'm now suspecting that what I'm seeing is the way it's supposed to work. I had been thinking the 16-char App specific pw was a "Salt" kind of thing to protect the Gmail server. I have now read that it's really just an alternative password for my Gmail account. If anyone can confirm or deny this new perspective, I would be grateful.
public static void sendEmail(String msgHeader, String msg, String emailId, String emailFrom) {
Properties props = new Properties();
props.put("mail.smtp.auth", "false");
props.put("mail.debug", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", mailServer);
props.put("mail.smtp.port", port#);
props.put("mail.smtp.auth.mechanisms", "NTLM");
props.put("mail.smtp.auth.ntlm.domain", domainName);
Session session = Session.getDefaultInstance(props, null);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailFrom));
to = emailId;
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(msgHeader);
message.setText(msg, "utf-8", "html");
message.saveChanges();
session.getDebug();
Transport.send(message);
// Copy message to "Sent Items" folder as read
Store store = session.getStore("ntlm");
store.connect(mailServer, emailFrom, pwd);
Folder folder = store.getFolder("Sent Items");
folder.open(Folder.READ_WRITE);
message.setFlag(Flag.SEEN, true);
folder.appendMessages(new Message[] {message});
store.close();
} catch (Exception ex) {
logger.error("Error occured while sending Email !", ex);
}
}
When I try to execute the code above, i am able to send out the emails. the issue is with saving the email. I get an error (NoSuchProviderException) at the line
Store store = session.getStore("ntlm");
I have a few questions on this:-
The email sending part works without password verification with ntlm. Is it possible to save the sent email into the sent items folder without password verification. If yes then how?
session.getStore doesnt work when i use
a. smtp - exception (Invalid provider)
b. ntlm - exception (NoSuchProviderException)
what should i use here.
Thanks in advance for your help.
"ntlm" is not a type of Store, it's an authentication mechanism. The store types supported by JavaMail are "imap" and "pop3". You almost certainly want "imap". Just like sending, you're going to need to supply your username and password when connecting to your imap server.
Also, upgrade to the current version of JavaMail if possible.
I need to send at least 200 messages from a stretch. When the program starts, send mail successfully to 15 or 17, then I get this error:
MESSAGE ERROR:
com.sun.mail.smtp.SMTPSendFailedException: 421 4.4.2 Message submission rate for this client has exceeded the configured limit
What I can do?
CODE JAVA
public void mandarEmail(String correos, String mensaje, String asunto) {
Message message;
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.port", "587");
props.put("mail.smtp.host", "pod51004.outlook.com");
props.put("mail.smtp.debug", "true");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("docemail#usmp.pe", "docpass");
}
});
try {
message = new MimeMessage(session);
message.setFrom(new InternetAddress("USMP - FN <documentos-fn#usmp.pe>"));
message.setSubject(asunto);
message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(correos));
message.addRecipients(Message.RecipientType.BCC, new InternetAddress[]{new InternetAddress("ivan_pro_nice#hotmail.com")});
message.setContent(mensaje, "text/html; charset=utf-8");
Transport transport = session.getTransport("smtp");
transport.connect("docemail#usmp.pe", "docpass");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
} catch (MessagingException e) {
throw new RuntimeException(e);
} finally {
props = null;
message = null;
}
}
That's the server you're connecting to, and not a client issue. Here's a doc on how to parse SMTP codes from the server.
A mail server will reply to every request a client (such as your email
program) makes with a return code. This code consists of three
numbers.
In your case, you're getting 421.
You probably need to pay for a "business" account from your mail server vendor so they'll let you send more email.
if you want to send single email to 200 clients. Than u can add an array of reciever's email addresses of size upto 50.
but i you want to send different msg for each email. Then you can create a new connection to email server with a counter that counts send emails as well as it counts 15 it should create a new connection.
to test your code use mailtrap.io
The following is the program, which I am trying to send e-mail. The code is error free and I don't get any run time exception. But the code is unable to send e-mail. I have revised this code a lot but can't get what is actually wrong.
The sender and the receiver both have GMail accounts. The sender has 2-step verification process disabled. (I don't think it matters for the receiver. Does it?)
The code :
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
class tester {
public static void main(String args[]) {
Properties props = new Properties();
props.put("mail.smtp.host" , "smtp.gmail.com");
props.put("mail.stmp.user" , "username"); // username or complete address ! Have tried both
Session session = Session.getDefaultInstance( props , null);
String to = "me#gmail.com";
String from = "from#gmail.com";
String subject = "Testing...";
Message msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(from));
msg.setRecipient(Message.RecipientType.TO , new InternetAddress(to));
msg.setSubject(subject);
msg.setText("Working fine..!");
System.out.println("fine!!??");
} catch(Exception exc) {
System.out.println(exc);
}
}
}
Well, your code doesn't actually attempt to send the message. Take a look at Transport.send.
Here are some examples:
http://www.javapractices.com/topic/TopicAction.do?Id=144
http://www.vipan.com/htdocs/javamail.html
First of all, you forgot to call Transport.send() to send your MimeMessage.
Secondly, GMail needs to be configured to use TLS or SSL connection. The following needs to be added to your Properties (props):
//To use TLS
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
//To use SSL
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
To connect to GMail SMTP, use the Transport.connect() method. I see you are not using any Transport at all in your code, so add this:
Transport transport = session.getTransport();
//Connect to GMail
transport.connect("smtp.gmail.com", 465, "USERNAME_HERE", "PASSWORD_HERE");
transport.send(msg);
Alternatively, you can create a Session by including a javax.mail.Authenticator as a parameter.
Example:
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("USERNAME_HERE", "PASSWORD_HERE");
}
});
I hope this helps you.
Resources:
Send email with SMTPS (eg. Google GMail) (Javamail)
JavaMail API – Sending email via Gmail SMTP example
I am writing a simple Java program to send mail, but am getting errors. Here's the code:
package mypackage;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
// Send a simple, single part, text/plain e-mail
public class Sendmail {
public static void main(String[] args) {
// SUBSTITUTE YOUR EMAIL ADDRESSES HERE!!!
String to = "atul.krbhatia#gmail.com";
String from = "atul.krbhatia#gmail.com";
// SUBSTITUTE YOUR ISP'S MAIL SERVER HERE!!!
String host = "smtp.gmail.com";
// Create properties, get Session
Properties props = new Properties();
// If using static Transport.send(),
// need to specify which host to send it to
props.put("mail.smtp.host", host);
// To see what is going on behind the scene
props.put("mail.debug", "true");
Session session = Session.getInstance(props);
try {
// Instantiatee a message
Message msg = new MimeMessage(session);
System.out.println("in try blk");
//Set message attributes
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("Test E-Mail through Java");
msg.setSentDate(new Date());
// Set message content
msg.setText("This is a test of sending a " +
"plain text e-mail through Java.\n" +
"Here is line 2.");
//Send the message
Transport.send(msg);
}
catch (MessagingException mex) {
// Prints all nested (chained) exceptions as well
System.out.println("in catch block");
mex.printStackTrace();
}
}
}//End of class
Here's the errors:
221 2.0.0 closing connection d1sm3094152pbj.24
in catch block
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. d1sm3094152pbj.24
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057)
at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1580)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1097)
at javax.mail.Transport.send0(Transport.java:195)
at javax.mail.Transport.send(Transport.java:124)
at mypackage.Sendmail.main(Sendmail.java:48)
Gmail only supports SMTP over SSL/TLS.
Add
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
You also need to login to the server:
props.put("mail.smtp.host", "smtp.gmail.com");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
});
A simple google search for "javamail gmail" will yield many example of how to use JavaMail with GMail, like this one. Google also has a configuration page listing the connection configuration that you'll need so you can double check the settings.
This URL May help:
http://sbtourist.blogspot.com/2007/10/javamail-and-gmail-its-all-about.html
It looks like the server is expecting SSL. There are several other questions on here where people are also trying to send mail through Gmail using Java, I recommend taking a look at them.
How can I send an email by Java application using GMail, Yahoo, or Hotmail?
Must issue a STARTTLS command first. Sending email with Java and Google Apps