I'm currently working on a spring boot application when i'm required to send mail at specific moment, so i used the javax.mail api to do so, the program works fine on local machine but when i deploy the application in google cloud app engine, i keep getting the following error:
javax.mail.AuthenticationFailedException
i tried to follow google cloud documentation instructions when it comes to mailing requirement but i keep getting the same error.
following my code.*
public boolean sendMail(String indicator, String destination, String hotelName, String username, String password) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "587");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(env.getProperty(IConstants.mailAddress),
env.getProperty(IConstants.mailPass));
}
});
String indic = null;
if(indicator.equals("R")){
indic = "RECEPTIONIST";
}
if(indicator.equals("M")){
indic = "ROOMMAID";
}
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(env.getProperty(IConstants.mailAddress)));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(destination));
message.setSubject(indic + "Hotel " + hotelName + " - Credentials");
message.setText("Hello " + hotelName
+ " Employee, Down Below Your Credentials for a secure access to your workspace " + ".\n USERNAME: "
+ username + " PASSWORD: " + password + ".\n" + "Greetings.");
Transport.send(message);
return true;
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
The sender mail is on the authorized mail senders list, everything is correctly configured, the app responds to all the requests, but keeps failing at sending mail step.
I enabled the less security application authentication option on the sender gmail account but it keep rejecting the authentication attempts.
Thanks.
I kept trying multiple configurations to make it work but it didn't, so i switched to another option, i implemented the sendGrid solution, google cloud listed it as a possible alternative approach, it was so simple, so secure and it worked from first attempt.
SendGrid implementation
Thanks for ur suggestions
Were you using standard env or flexible env. In our case we used flexible env with google smtp mailing.
It is working fine for us. And I suspect the issue in your case is with the third party access check of google mail account.
Try the same smtp after enabling this option so that your application will be able to access the gmail smtp.
Turn on access from the settings shown in screenshot for the account which is being used from smtp
Although the sendgrid is a nice mailing service. But we prefered google smtp only.
Related
I am attempting to send mail using Java to a Gmail account, code below. I appear to be doing everything correctly, however I receive an authentication failure. Google wants me to turn on the "less secure app" feature to enable transmission.
Is there a way to code in such a way that Gmail is happy with Java and will not throw the "turn on less secure apps" fault?
Error:
javax.mail.AuthenticationFailedException: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=...U
534-5.7.14 FigguJaZwDtp...
534-5.7.14 ...o> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14 Learn more at
534 5.7.14 https://support.google.com/mail/answer/... - gsmtp
Code:
String hostSmtpUser = "myemail#gmail.com";
String host = "smtp.gmail.com";
String hostPort = "587";
String hostSmtpPassword = "thepassword";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.user", hostSmtpUser);
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.starttls.enable", "true");
properties.setProperty("mail.smtp.port", hostPort);
properties.setProperty("mail.smtp.auth", "true");
Session oSession;
if (true == ToolsCommon.isEmpty(hostSmtpUser))
oSession = Session.getInstance(properties);
else
oSession = Session.getInstance(properties, new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(hostSmtpUser, hostSmtpPassword);
}
});
// Compose the message
try
{
MimeMessage message = new MimeMessage(oSession);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(Subject);
message.setText(Body);
// Send message
Transport.send(message);
}
catch (MessagingException ex)
{
// Log the error.
ToolsLog.logError(TypeLog.ui, ex);
}
I already did research, so the code to my knowledge is not the problem, just do not see a workaround for the less secure apps message.
References:
Ref 1
Ref 2
Ref 3
Ref 4
By default, GMail doesn't allow password-based authentication -- that's why you'd have to allow "less-secure apps" to use your program as-is.
Instead, you can use OAuth 2.0 to avoid using a password directly. That method is considered secure by Google and won't require changing any account settings.
Less secure apps (https://myaccount.google.com/u/0/lesssecureapps) options is disabled and we can longer use it to send mail.
But there is a better option provided by google - apppasswords
https://myaccount.google.com/u/0/apppasswords
Use 16 digit code provided by google instead of password and that should be it.
Note: 2-factor authentication needed to be enabled before using appspasswords.
I am stuck behind a corporate firewall that won't let me send email via conventional means such as Java Mail API or Apache Commons Email, even to other people inside the organization(which is all I want anyways). But my Outlook 2010 obviously can send these emails. I was wondering if there is a way to automate Outlook 2010 via Java code so that Outlook can send the emails ? I know stuff like "mailto" can be used pop-up the default Outlook send dialog with pre-populated info, but I am looking for a way to have the send operation happen behind the scenes. Thanks for any info.
You can send emails through outlook with javamail use the configurations described on Outlook's official site.
Here is small demo code
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public static void main(String[] args) {
final String username = "your email"; // like yourname#outlook.com
final String password = "*********"; // password here
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp-mail.outlook.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
session.setDebug(true);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("receiver mail")); // like inzi769#gmail.com
message.setSubject("Test");
message.setText("HI you have done sending mail with outlook");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
.
Note: I tested this with Javamail API 1.5.6
I don't think there's any way to do what you want using Outlook.
Presumably your mail server is also behind the corporate firewall. If you're using Outlook for your client, you're probably using Exchange for your server. Exchange can be configured to support the standard SMTP protocol for sending mail, which would allow use of JavaMail. If you can't configure your Exchange server to support SMTP, you still might be able to use Exchange Web Services. If that doesn't work, you might need to use one of the JavaMail Third Party Products that supports the Microsoft proprietary mail protocol.
Process p = Runtime.getRuntime().exec("cmd /C start outlook ");
The code I am currently using is as follows:
String to = "....#gmail.com";
String from = ".....#gmail.com";
String host = "127.0.0.1";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
If I paste the above code in my Java servlet and run it, the following exception gets thrown:
javax.mail.NoSuchProviderException: smtp
I have also tried following the solutions outlined in these resources but to no avail: link1 link2 link3 link4.
It would help if you included the the full stacktrace for the javax.mail.NoSuchProviderException and JavaMail debug output. Because you are running this in a servlet container you could be running into Bug 6668 -skip unusable Store and Transport classes. Change your call to Transport.set to the following:
final ClassLoader ccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(Session.class.getClassLoader());
try {
Transport.send(message);
} finally {
Thread.currentThread().setContextClassLoader(ccl);
}
That code will isolate which transport class the code is allowed to see. That will rule out that bug in your code.
NoSuchProviderException means something is messed up in your JavaMail API configuration. Where and how have you installed the JavaMail jar file?
Also, in case it's not clear from the other responses, the only way you're going to be able to send mail without authentication is if you're running your own mail server. You can't do it with general purpose online e-mail services (e.g. Gmail).
First of all, if you wanna use gmail to send emails from your program you need to define stmp host as gmail. Your current host "127.0.0.1" is localhost meaning your own computer? Do you have mail server running on your computer?
Here you can see some tutorial how to send an email using gmail: http://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
If you're afraid to pass your normal gmail account details then create some kind of test email like kselvatest or something.
You are missing pretty much those:
final String username = "username#gmail.com";
final String password = "password";
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");
props.put("mail.smtp.port", "587");
So basicly all you need to add is:
1.login and password so JavaMail can use some gmail account
2.declare which mail server you wanna use
change String host = "127.0.0.1"; to String host = "smtp.gmail.com";
3.set mail port
For this code you should get javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 25; exception
But I suspect you have a jre issue. May be smtp implementation has a problem. Why don't you download java mail implementation from http://www.oracle.com/technetwork/java/javamail/index-138643.html and add it to your project class path and try?
Im tring to send a simple email with this code using google app engine.
But nothing happens, is there something i have to configure in order to use the mail api?
This runs on localhost.
I am using gmail as mail host.
String host = "smtp.google.com";
String to = "example#yahoo.fr";
String from = "example#gmail.com";
String subject = "this is a test";
String messageText = "test";
boolean sessionDebug = false;
// Create some properties and get the default Session.
Properties props = System.getProperties();
props.put("mail.host", host);
props.put("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props, null);
// Set debug on the Session
// Passing false will not echo debug info, and passing True will.
mailSession.setDebug(sessionDebug);
// Instantiate a new MimeMessage and fill it with the
// required information.
Message msg = new MimeMessage(mailSession);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = { new InternetAddress(to) };
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setText(messageText);
// Hand the message to the default transport service
// for delivery.
Transport.send(msg);
When running the AppEngine development server locally, anything sent via the Mail service will not actually be sent - it will just be logged to the console
See here
When an application running in the development server calls the Mail service to send an email message, the message is printed to the log. The Java development server does not send the email message.
In addition, the from address must be (from here)
The email of an app administrator
The email of the currently logged in user who signed in using a Google Account
A valid email receiving address from the app
The sender should be your own Gmail email address instead of example#gmail.com
Reason is because the SMTP server needs to authenticate you.
Apparently, GAE doesn't allow the use of the admin accounts any more. you need to use the service account: project-id#appspot.gserviceaccount.com
My previous projects still work with admin accounts, but the recently created projects just don't allow me to use any of the admin accounts.
Other than email not working on localhost or due to the sender email not being the authenticated one, I have experienced that email does not work even when the version is not the default one. I could not find this documented anywhere.
For example:
nondefaultversion-dot-myapp.appspot.com (email does not work, no error logs)
myapp.appspot.com (email works)
Please confirm if others have also faced this issue.
I have tried to use Javamail to send emails. However, I received the following message:
javax.mail.SendFailedException: Send failure (javax.mail.MessagingException: Illegal Arguments (java.lang.IllegalArgumentException: Bad Request: ))
I have tried to send emails from the admin account (that I use to upload the app), as well as the user account I login to the app as. (from UserService - getCurrentUser().getEmail()) both failed.
I'm wondering whether there's any special setting I have to setup?
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(session);
UserService userService = UserServiceFactory.getUserService();
String email = userService.getCurrentUser().getEmail();
//Or
//String email = "my_admin_account#gmail.com";
msg.setFrom(new InternetAddress(email));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress("some_test_email#gmail.com"));
msg.setSubject("Test Email");
msg.setText("Nobody");
Transport.send(msg);
That is really very odd. I just wrote the following sample:
UserService userService = UserServiceFactory.getUserService();
String thisURL = request.getRequestURI();
if (request.getUserPrincipal() != null) {
response.getWriter().println("<p>Hello, " +
request.getUserPrincipal().getName() +
"! You can <a href=\"" +
userService.createLogoutURL(thisURL) +
"\">sign out</a>.</p>");
Properties props = new Properties();
Session mailSession = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(mailSession);
String email = userService.getCurrentUser().getEmail();
//Or
//String email = "my_admin_account#gmail.com";
msg.setFrom(new InternetAddress(email));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress("jesse.sightler#gmail.com"));
msg.setSubject("Test Email");
msg.setText("Nobody");
Transport.send(msg);
response.getWriter().println("<p>Sent email!</p>");
} else {
response.getWriter().println("<p>Please <a href=\"" +
userService.createLoginURL(thisURL) +
"\">sign in</a>.</p>");
}
There were no exceptions, and I did receive the email. Are you sure there isn't more going on in the actual application?
Just scanning the documentation on this I found the following:
For security purposes, the sender
address of a message must be the email
address of an administrator for the
application, or the Google Account
email address of the current user who
is signed in. The email address can
include a "reply to" address, which
must also meet these restrictions.
So 'email' should at the very least be set back to your admin emailaccount,
or a dedicated emailaccount added as an administrator to your project..
Other than that I see no problems with your code..
my two cents!! Check if the functionality is part of the server rather than the client classes..
Most probably because you are running your application locally.
Upload it to app-engine and it will work fine.
*your sender email should be the mail id with which you deploy the project to app-engine*
or an admin mail id.
Make sure you are using the message from an email address corresponding to the currently logged-in user or the email of the account where the applications is deployed.
The most important thing is that messages are not sent if the application is run locally. To actually send the messages, deploy it into Google App Engine and run it remotely.