Unable to email in HTML format. - java

I am trying to send email in HTML format. It is working for text/plain. But when i set content type to text/html mail is not being transported(no exception is being thrown but i don't get email as well).
Following is my code.
public void postMail() throws Exception {
boolean debug = false;
Properties props = new Properties();
props.put("mail.smtp.host", smtpServer);
props.put("mail.smtp.port", smtpServerPort);
props.put("mail.smtp.auth", "false");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback","false");
lgr.debug(lgr.isDebugEnabled()?"SMTP Server --->" + smtpServer : null);
Session session = Session.getInstance(props, null);
session.setDebug(debug);
Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
// Here is some logic to add TO and CC and BCC
msg.setSubject(subject);
// writer.println("Subject : " + subject);
lgr.debug(lgr.isDebugEnabled()?"Subject : " + subject : null);
msg.setContent(message, "text/html");
Transport.send(msg);
lgr.info(lgr.isInfoEnabled() ?"Mail sent": null);
}
Any help in this regard will be highly appreciated.

Get rid of the socket factory stuff, you don't need it.
When you set debug to true, do you see any errors in the debug output? Or is your mail server accepting the message without complaint? If no errors, then most likely the problem is that the recipient's mail server thinks your message is spam, although that seems unlikely with your simple test message.
Have you tried sending to different recipients, especially different recipients using different mail servers? It would be useful to figure out if the problem is with the recipient's mail server or with the mail server you're using for sending.

I faced a similar issue some times back. I found that the issue was with the html content containing single quotes.
As a test try to send a (simple word)/(simple html without quotes at all) as message using text/html format. If that works you can probably modify your html message to contain only double quotes.
Hope that helps!

Related

Getting this error while trying to send mail using smtp server from java! how to solve this

So i am trying to send a pdf through mail using Gmail smtp port 465 but it keeps on throwing this error,
googled it but couldn't solve this.
i don't understand whats wrong? help me on this?
thanks in advance
tried:
1.changing ports
2.tried to correct something on certificates didn't work
error:
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sample.pdf.PDFMailing.pdfMail(PDFMailing.java:72)
at com.sample.pdf.GeneratePdf.addDataToPdf(GeneratePdf.java:42)
at com.sample.pdf.Report.main(Report.java:47)
PDFMailing.java
public static void pdfMail(String file){
//Sender email-ID and Password.
final String senderEmail="xxxxxx";//Sender Mail ID
final String password="xxxxx";//Sender Mail ID Password.
//setting the Properties.
Properties props=new Properties();
props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
props.put("mail.smtp.port", "465"); //SMTP Port
//Authenticating the mailID of the sender.
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
return new javax.mail.PasswordAuthentication(senderEmail, password);
}
};
//Creating and getting the Session Object.
Session session=Session.getInstance(props, auth);
//Setting the From, To, Subject, MessageBody.
try{
Message message=new MimeMessage(session);
message.setFrom(new InternetAddress(senderEmail));//Sender Mail ID
message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("harshapirate#gmail.com"));//Receiver Mail ID
message.setSubject("Sample ECO PDF file");
message.setText("This a Sample ECO PDF file.");
MimeBodyPart bodyPart=new MimeBodyPart();
Multipart multipart=new MimeMultipart();
bodyPart.setText("This is multipart Text.");
//Attachments for any file.
MimeBodyPart pdfAttachment=new MimeBodyPart();
pdfAttachment.attachFile(file);
//Attach the Body part to the Multipart.
multipart.addBodyPart(bodyPart);
multipart.addBodyPart(pdfAttachment);
//Associate multipart to the message.
message.setContent(multipart);
System.out.println("Sending mail is in process.......");
//sending the message to-address mail.
Transport.send(message);
System.out.println("Mail has been sent sucessfully.");
}
catch(Exception e){
throw new RuntimeException(e);
}
}
I presume that is Java 8.0.251. Since you have the latest Java 8 release then this should not be happening:
The root certificates in a 8.0.251 keystore should all be current.
The real smtp.google.com should be using well-known root certificates.
The real smtp.google.com would not be presenting the cert chain in the wrong order.
So I think that something is else "getting in the way". Likely explanations include:
Something that is sending outgoing email connections through an SMTP proxy; e.g. a firewall or anti-virus product.
You are running on an application server that has overridden the set of trusted certificates provided by the JDK.
It is also possible that something has subverted your DNS or IP routing and you are talking to a spoofed "smtp.gmail.com" server.
Check the following:
Check if latest JDK is installed (Command: java -version) so that it has latest
certificates and updated CA's.
Check if there are multiple JDKs or JREs installed: If so remove them.
Check if JAVA_HOME is pointing to the latest JDK you installed.
(Command: echo $JAVA_HOME in linux Or echo %JAVA_HOME% in Windows command prompt)
Check if your system date and time are correct.
If above is verified then your Java installation is fine.
Code:
I see a missing property in your code: props.put("mail.smtp.starttls.enable", "true").
Add it and try.
Hope you are able to access Gmail from your browser at least. This confirms that your machine is able to access Gmail servers - Though not an exact test for SMTP, but it is still good to test.
If you are running inside Tomcat, then ensure you have the latest version and hope it has its certificate store not customized or altered in some way.
If everything above is OK, then either you are behind some proxy or you are hacked.
Maybe check for a system property or other way that someone has defined a different trust store e.g. with: -Djavax.net.ssl.trustStore=somefilename.jks
See: https://www.baeldung.com/java-keystore-truststore-difference
But the default truststore should be $JAVA_HOME/jre/lib/security/cacerts (but its contents vary between the Oracle JDK and OpenJDK - this was later fixed, see: https://openjdk.java.net/jeps/319 )
Inspecting/modifying the contents of the store can be done with the command line tool: keytool or a GUI like: https://keystore-explorer.org/
Before you go crazy try starting your application with the following extra System Property for java (-Dsystempropertyname=value):
-Djavax.net.debug=all
Then you will exactly see all details of the used trust store and offered certificates from the server, details of the SSL/TLS handshake and even all data encrypted/decrypted.
For all the information there is on this subject see the JSSE Reference Guide for your Java version, e.g.: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html
The same kind of code, I have written earlier and is in working state. Could you please give a try on using this code below:
Also, check the proper version of Java installed 8+ in your system, with all the Environment variables properly set and required for your project. If any proxy settings exists in your system, try to remove it and then again running the code.
//this will work only for gmail.
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import com.[MyProjectRelatedImports].pojo.EmployeeDetails;
public class SendEmail {
public static void sendMail(List<EmployeeDetails> emplDetails) {
Address[] to = new Address[emplDetails.size()];
try {
for (int i = 0; i < to.length; i++) {
to[i] = new InternetAddress(emplDetails.get(i).getEmail());
}
} catch (MessagingException e) {
e.printStackTrace();
}
// Recipient's email ID needs to be mentioned.
String tom = "xyz#gmail.com";// address of recipient
// Sender's email ID needs to be mentioned
String from = "abc#gmail.com"; //address of sender
// Assuming you are sending email from localhost
String host = "smtp.gmail.com";
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.user", "emailID"); // User name
properties.put("mail.smtp.password", "password"); // password
properties.put("mail.smtp.port", "587");// default mail submission port
properties.put("mail.smtp.auth", "true");
// Get the default Session object.
Session session = Session.getDefaultInstance(properties, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("emailID", "password"); // username will be your email address and password same as your Gmail account.
// And if your account is protected with 2 step verification then you need to generate the app password from the link provided
//https://security.google.com/settings/security/apppasswords
}
});
try {
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header. //message.addRecipient(Message.RecipientType.TO, new InternetAddress(tom));
//Send Email to multiple recipients
message.addRecipients(Message.RecipientType.TO, to);
// Set Subject: header field
message.setSubject("Subject text via Java Class");
// Now set the actual message
message.setText("Message Content should be written here!!! Regards: Pratishtha Sharma ");
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mEx){
mEx.printStackTrace();}
}
}

MailConnectException : nested exception: java.net.SocketException: Permission denied: connect

I was trying to send a mail from gmail id to another using this example. Here is my file:
public class SendHTMLEmail
// Recipient's email ID needs to be mentioned.
String to = "harsh.hr99#gmail.com";
// Sender's email ID needs to be mentioned
String from = "web#gmail.com";
// Assuming you are sending email from localhost
String host = "localhost";
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.user", "Admin");
properties.setProperty("mail.password", "admin");
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Send the actual HTML message, as big as you like
message.setContent("<h1>This is actual message</h1>", "text/html" );
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
}catch (MessagingException mex) {
mex.printStackTrace();
}
I am running Tomcat server on localhost:9091 port. I am receiving following error:
screen shot from cmd
how do I solve this?
Well, you set "host = localhost" so your program will try to use a smtp server located at localhost. Problem is: You don't have (and don't want) a smtp server at localhost installed. At least it seems like that.
I think what you want to do is: http://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
If you trying this example you will need to keep in mind not to publish it because it contains hard-coded gmail credentials.

Server error when sending mail via jsp

I've a button on my application that has to check if inputted data is correct, adds it to a database and sends an email, it's represented by the following code:
<%# page import = "java.text.*" %>
<%# page import="java.io.*,java.util.*,javax.mail.*, javax.mail.Service"%>
<%# page import="javax.mail.internet.*,javax.activation.*"%>
<%# page import="javax.servlet.http.*,javax.servlet.*" %>
[...]
<a href="javascript:void();" onclick="
javascript:if(confirmaEnviar())$('#usuario').submit();
<% String result;
// Recipient's email ID needs to be mentioned.
String host = "smtp.gmail.com";
String to = "existingdirection#gmail.com";
String from = "existingdirection2#gmail.com";
String subject = "test";
String messageText = "body test";
Properties props = System.getProperties();
props.put("mail.host", host);
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", "25");
// If using authentication, otherwise comment out
props.put("mail.smtp.auth", "true");
// Gmail requires TLS, your server may not
props.put("mail.smtp.starttls.enable", "true");
Session mailSession = Session.getDefaultInstance(props, null);
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);
Transport transport = mailSession.getTransport("smtp");
//connect with authentication
transport.connect(host,"existingdirection2#gmail.com" , "password");
transport.sendMessage(msg, address);
transport.close();
%>
return false;" class="button button-alt">ENVIAR</a></div>
But if I upload it and try to execute it I get an error in the browser: Error: Server Error
The server encountered an error and could not complete your request.
I had thought that it might be that jsp code couldn't be called that way (in the middle of an onclick) but if I put it into another place of the code (in the middle of html tags) the error still reproduces.
I've added the library for java mail to the java build path and I've also copied it to the lib directory.
Of course it has been tested that what fails is the email related code, if I delete it from the application the rest goes nicely.
Email directions of passwords have also been checked to be correct.
I'm using GAE to host the application.
Any idea of what might be happening?
I'm grateful for your help.
Edit: That's the stack trace, guess it's not really a code related question after all..
com.google.apphosting.api.ApiProxy$FeatureNotEnabledException: The Socket API will be enabled for this application once billing has been enabled in the admin console. at java.lang.Thread.getStackTrace(Thread.java:1567) at com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:259) at com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:68) at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:202) at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:199) at java.security.AccessController.doPrivileged(Native Method) at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:199) at com.google.apphosting.runtime.ApiProxyImpl.makeSyncCall(ApiProxyImpl.java:68) at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:107) at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:56) at com.google.appengine.api.socket.SocketApiHelper.apiProxyMakeSyncCall(SocketApiHelper.java:90) at com.google.appengine.api.socket.SocketApiHelper.makeSyncCall(SocketApiHelper.java:58) at com.google.appengine.api.socket.NameServiceImpl.lookupAllHostAddr(NameServiceImpl.java:61)
Strnage thing is that there's no API called Socket API in Google Api's console, guess I'll also try to contact a google consultor also.
GAE comes with it's own SMTP server, so you do not need to set your own SMTP parameters: https://developers.google.com/appengine/docs/java/mail/usingjavamail
However, if you do set your own SMTP parameters then GAE will use sockets which have this limitations. These apply in your case:
Sockets are available only for paid apps - this is the one producing Error.
Port 25 (SMTP) is blocked
Google IP ranges are blocked, except Gmail SMTPS: smtp.gmail.com port 465 and 587

Java add header in MimeMessage msg

Problem that i'm solving is that when i send mail if the recipient (to mails, cc/bcc) not exist, i don't want sender to get Delivery Status Notification (Failure) mail.
The solution that i'm implementing is adding new header in mail Prevent-NonDelivery-Report
I want to add new header in MimeMessage msg in java
// this is part of the code that defined the mime message
Session session = Session.getDefaultInstance(props, null);
// we create message
Message msg = new MimeMessage(session);
// this code is not working for me
msg.addHeader("Prevent-NonDelivery-Report", "");
I found the solution i add props.setProperty("mail.smtp.dsn.notify", "NEVER") to the property of the session and that fix my problem
On behalf of the OP:
I found the solution. I add:
props.setProperty("mail.smtp.dsn.notify", "NEVER")
to the property of the session and that fix my problem.

Apache Commons Email and Reusing SMTP Connections

Currently I am using Commons Email to send email messages, but I have not been able to find a way to share smtp connections between emails sent. I have code like the following:
Email email = new SimpleEmail();
email.setFrom("example#example.com");
email.addTo("example#example.com");
email.setSubject("Hello Example");
email.setMsg("Hello Example");
email.setSmtpPort(25);
email.setHostName("localhost");
email.send();
Which is very readable, but is slow when I do a large amount of messages, which I believe is the overhead of reconnecting for each message. So I profiled it with the following code and have found that using the reusing the Transport makes things about three times faster.
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect("localhost", 25, null, null);
MimeMessage message = new MimeMessage(mailSession);
message.setFrom(new InternetAddress("example#example.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("example#example.com"));
message.setSubject("Hello Example");
message.setContent("Hello Example", "text/html; charset=ISO-8859-1");
transport.sendMessage(message, message.getAllRecipients());
So I was wondering if there was a way to make Commons Email reuse an SMTP connection for multiple email sendings? I like the Commons Email API better, but the performance is kind of painful.
Thanks,
Ransom
I came up with the following solution after digging into the commons source itself. This should work, but there may be better solutions I do not know of
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect("localhost", 25, null, null);
Email email = new SimpleEmail();
email.setFrom("example#example.com");
email.addTo("example#example.com");
email.setSubject("Hello Example");
email.setMsg("Hello Example");
email.setHostName("localhost"); // buildMimeMessage call below freaks out without this
// dug into the internals of commons email
// basically send() is buildMimeMessage() + Transport.send(message)
// so rather than using Transport, reuse the one that I already have
email.buildMimeMessage();
Message m = email.getMimeMessage();
transport.sendMessage(m, m.getAllRecipients());
Could we not achieve this easier by getting the mail session from the first email using getMailSession() and putting it to all subsequent messages using setMailSession() ?
Not 100% sure what the
Please note that passing a username and password (in the case of mail authentication) will create a new mail session with a DefaultAuthenticator. This is a convience but might come unexpected. If mail authentication is used but NO username and password is supplied the implementation assumes that you have set a authenticator and will use the existing mail session (as expected).
from the javadoc means, though :-/
http://commons.apache.org/email/api-release/org/apache/commons/mail/Email.html#setMailSession%28javax.mail.Session%29
see also:
https://issues.apache.org/jira/browse/EMAIL-96
not sure how to continue here...

Categories

Resources