A friend of mine has a new website and i build him a tool to organize email-addresses and send newsletters (HTML-Messages). Therefore i use the javax.mail library. While developing i sent all mails from my gmail account and it worked fine. But now, for "production", i want to send the mails from his domain, which is hosted by 1und1.
I am able to connect successfully to the 1und1 smtp-Server, but as soon as i send a mail, i get the following errors:
com.sun.mail.smtp.SMTPSenderFailedException: 550-Requested action not taken: mailbox unavailable
550 invalid DNS MX or A/AAAA resource record
When sending from the online 1und1 webmailer, i can send to any mailadress without errors.
These are the props i set for mailing. Like i said, i can connect to the server with these information, but sending fails.
Properties props = new Properties();
// Zum Senden
props.setProperty("mail.smtp.starttls.enable" , "true");
props.setProperty("mail.smtp.host", configurationService.getMailHost()); // smtp.1und1.de
props.setProperty("mail.smtp.auth", configurationService.getMailAuth().toString()); // true
props.setProperty("mail.smtp.port", configurationService.getMailPort()); // 587
props.setProperty("mail.smtp.user", user);
props.setProperty("mail.smtp.password", pass);
return Session.getInstance(props, new javax.mail.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(props.getProperty("mail.smtp.user"),
props.getProperty("mail.smtp.password"));
}
});
Thanks for help!
Edit: When Debugging the Session, i get the following line just before the exception occurs:
MAIL FROM: <USER#LAPTOP-Name.fritz.box>
How can i change this to something accepted?
Related
I have a Spring Boot application that sends emails. For any action that requires notification, a Mail instance is created with status PENDING in the database and a job is run to send the pending emails every minute. The status of the Mail instances are set as PENDING, SENT or FAILED.
try {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.from", myEmailAddress);
props.put("mail.smtp.timeout", 2000);
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
MimeMessage message = new MimeMessage(session);
MimeMultipart content = getContent(mail, message, username);
message.setContent(content);
Transport.send(message);
mail.setStatus(MailStatus.SENT);
mailService.save(mail);
} catch (MailConnectException mce) {
mail.setStatus(MailStatus.FAILED);
mailService.save(mail);
} catch (Exception e) {
// other actions
}
Now, this works fine if a valid email id is provided. But when the receiving email address is a non-existent one like somerandomname#gmail.com, there are no exceptions thrown. From what I read from similar questions in SO and elsewhere, I understand that mail sending is an asynchronous process and hence there is no way to determine that a given email is existing or not (or other issues like Inbox full). That is why after the Transport.send(message); statement, the mail.setStatus(MailStatus.SENT); statement will always be executed irrespective of the email address being present. Later the mail will actually be attempted to be sent and I get an email in myEmailAddress with content like the following:
The response from the remote server was: 550 5.1.1
somerandomname#gmail.com User unknown
Okay, accepted until this point. But now I need a way to alert the user that the email couldn't be sent because they entered an invalid email so that they can update their email. More specifically, I need to set the status of the Mail instance to FAILED. What is the best way to achieve this?
If you use a service like AWS SES to send your mail, you can receive notifications about bounces (and complaints) either simply as notifications for a human to read, or as programmatic triggers that could be used to call an alert endpoint on your spring boot server, for example through AWS Lambda. There are other services that may be able to do the same, such as SendGrid.
Your Spring Boot application would have to retrieve the notifications (an email itself) from your inbox corresponding to the sender address of the initial email. There are various options how to achieve this:
Use a service with provides callbacks (triggers) for incoming messages as mentioned by Benjamin
Poll your inbox using a standard protocol like POP or IMAP
Hint for the second option: https://docs.spring.io/spring-integration/reference/html/mail.html#mail-inbound
Everything works, including authentication, but when I get to the step of creating a folder the program crashes.
I've tried switching to SMTP, didn't work, not even sure what SMTP is,
I've Tried a different Gmail account,
I've tried removing the line properties.put("mail.pop3.starttls.enable", "true"), and
I've tried removing the 3's from pop3 and pop3s.
private static void createProperties() {
// Create properties field.
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.store.protocol", "pop3s");
properties.put("mail.pop3.port", "995");
//properties.put("mail.pop3.starttls.enable", "true");
emailSession = Session.getDefaultInstance(properties, null);
}
private static void createStore() throws MessagingException {
// Create the POP3 store object and connect with the POP server.
Store store = emailSession.getStore("pop3s");
store.connect(host, user, password);
}
private static void createFolder() throws MessagingException {
// Create the folder object and open it.
Folder emailFolder = store.getFolder("INBOX"); // Error here
emailFolder.open(Folder.READ_ONLY);
}
I expected to get some nicely formatted email messages.
I got the following errors:
DEBUG POP3: server doesn't support TOP, disabling it
Exception in thread "main" java.lang.NullPointerException
at GetMail.createFolder(GetMail.java:60)
at GetMail.main(GetMail.java:33)```
The POP3 protocol only supports one folder - Inbox. Use IMAP instead.
I have created automated email report using java mail api which needs to be triggered everyday after a batch file run.Although it works fine most of the times,at times it gives exception javax.mail.MessagingException: Could not connect to SMTP host: my host name, port: 25; nested exception is: java.net.ConnectException: Connection refused.This is not due to authentication issue as i use the same credentials whenever i sent the email.
I am not sure why java mail api fails intermittently.Can i get some suggestion to debug the issue?
I am using the below code snippet -
String to = "xyz#gmail.com";//change accordingly
String from = "abc#mydomain.com";//change accordingly
final String username = "abc";//change accordingly
final String password = "*****";//change accordingly
String host = "My SMTP server";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "25");
// Get the Session object.
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
message.setSubject("Testing Subject");
message.setText("message to stakeholders");
Transport.send(message);
}
It's a good idea to check logs on the mail server to see possible cause of the refusal - especially since you know WHEN failed attempts were made at.
If JavaMail can't connect "sometimes" with "connection refused", the possibilities are:
The server is actually down.
The server is up, but too busy to accept new connections.
The server is up, but is rejecting connections for some policy reason, e.g., you've connected too frequently.
Some firewall or anti-virus program has rejected the connection.
Check the server configuration and log files. If there's nothing on the server indicating that it's rejecting connections, check the client.
One of my customers is using Gmail for business (part of Google Apps) and I had to reconfigure the website I've developed so it would match the new credentials. After a bit of struggle due to TLS errors, I've managed to make the code work on localhost and on my test server (both Apache Tomcat 5.5). Everything was going smooth until I had to move it on his server (another Tomcat 5.5 as the hosting company told me). On the client's server I get the following error:
javax.mail.SendFailedException: Sending failed;
nested exception is:
class javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;
nested exception is:
java.io.IOException: Couldn't connect using "javax.net.ssl.SSLSocketFactory" socket factory to host, port: smtp.gmail.com, 465; Exception: java.lang.reflect.InvocationTargetException
The strange thing is that on localhost and the test server the port 465 works fine, and the guys from hosting said that port is opened on their server.
The code that connects to the mailserver is:
private void initConfigParams() throws CMSGeneralException {
try {
props = System.getProperties();
String smtpHost = Messages.getDBConfString("mail.smtp.host");
String mailPort = Messages.getDBConfString("mail.smtp.port");
String socketFallback = Messages.getDBConfString("mail.smtp.socketFactory.fallback");
String enableTls = Messages.getDBConfString("mail.smtp.starttls.enable");
String authSmtp = Messages.getDBConfString("mail.smtp.auth");
String tlsRequired = Messages.getDBConfString("mail.smtp.stattls.required");
String sktFactory = Messages.getDBConfString("mail.smtp.socketFactory.class");
props.put("mail.smtp.starttls.enable", enableTls);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.auth", authSmtp);
props.put("mail.smtp.starttls.required", tlsRequired);
props.setProperty("mail.smtp.socketFactory.class", sktFactory);
props.setProperty("mail.smtp.socketFactory.fallback", socketFallback);
props.setProperty("mail.smtp.port", mailPort);
props.setProperty("mail.smtp.socketFactory.port", mailPort);
props.put("mail.transport.protocol", Messages.getDBConfString("mail.transport.protocol"));
Authenticator auth = null;
userName = Messages.getDBConfString("mail.username");
userPassword = Messages.getDBConfString("mail.userpassword");
if (!CMSUtils.isEmptyString(userName) && !CMSUtils.isEmptyString(userPassword)){
/* props.put("mail.smtp.auth", "true"); */
auth = new SMTPAuthenticator(userName, userPassword);
}
session = Session.getDefaultInstance(props, auth);
session.setDebug(false);
address = new InternetAddress[1];
address[0] = new InternetAddress(recipients);
mbText = new MimeBodyPart();
mbText.setContent(text, "text/html");
mp = new MimeMultipart();
mp.addBodyPart(mbText);
} catch (MessagingException e) {
e.printStackTrace();
throw new CMSGeneralException();
}
}
With the following .properties file
mail.smtp.starttls.enable=true
mail.smtp.host=smtp.gmail.com
mail.smtp.auth=true
mail.smtp.starttls.required=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.port=465
mail.transport.protocol=smtps
mail.username=website#example.com
mail.userpassword=password
mail.from=website#example.com
mail.to=mail#example.com
I tried the other ports for GMail, 587, but it doesn't work on any of the servers. Not even port 25 won't do the trick.
So, what am I doing wrong, and what should I do to make the mailing work?
Get rid of all the socket factory properties; if you're using a reasonably recent version of JavaMail you don't need them. See the JavaMail FAQ for how to configure JavaMail to access Gmail. You'll also find debugging tips there if it still doesn't work.
Also, change Session.getDefaultInstance to Session.getInstance.
And finally, if you're setting "mail.transport.protocol" to "smtps", you need to set the other properties as "mail.smtps." properties, not "mail.smtp." properties.
It seems to you have problems with java.lang.reflect.InvocationTargetException. So, I mean it's not a network problem. May be you've specified some parameters wrong and JavaMail API routes couldn't invoke a method. May be you should also specify property mail.smtp.ssl.socketFactory.
Some documentation here http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html .
I have been working at home on Gmail-Imap-Api on the weekend. It was working Properly But when i returned to office and am trying here it throws exception.
Properties props = System.getProperties();
props.put("mail.store.protocol", "imaps");
props.put("mail.smtp.auth", "true");
try {
boolean debug = false;
Authenticator auth = new SMTPAuthenticator(
"***", "***");
Session session = Session.getInstance(props, auth);
session.setDebug(debug);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "***#gmail.com",
"****");
......
......
This was working fine at home netwrok.
Now i thought i would add proxy and added these lines of code.
System.setProperty("http.proxyHost", "****.com");
System.setProperty("http.proxyPort", "8080");
Still it doesnt work and the exception is.
com.google.code.javax.mail.MessagingException: imap.gmail.com;
nested exception is:
java.net.UnknownHostException: imap.gmail.com
at com.google.code.com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:665)
at com.google.code.javax.mail.Service.connect(Service.java:295)
at com.google.code.javax.mail.Service.connect(Service.java:176)
at openReports.OpenReportsProject.main(OpenReportsProject.java:43)
Caused by: java.net.UnknownHostException: imap.gmail.com
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:177)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:367)
at java.net.Socket.connect(Socket.java:524)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:545)
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:141)
at com.google.code.com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:288)
at com.google.code.com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:231)
at com.google.code.com.sun.mail.iap.Protocol.<init>(Protocol.java:113)
at com.google.code.com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:110)
at com.google.code.com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:632)
... 3 more
The proxy settings that you have entered will work only for HTTP connections. IMAP is a different protocol operating on a different port (993 in this case). If you are behind firewall, your firewall needs to allow connection to the external host:port AND the protocol. You need to request to your Network Administrator for this. Once the settings are in place you will be able to communicate to Gmail Imap server on default/specified port with specified protocol.