I work with log4j.properties through WSO2 products. I needed implement a appender to work with SMTPAppender and send emails notifications using gmail smtp server. So, when I config log4j and start ESB WSO2 Server, the manage console print: log4j:ERROR Could not instantiate class [com.notification.GmailSMTPAppender].
My implementation was:
package com.notification;
public class GmailSMTPAppender extends SMTPAppender {
protected Session session;
public GmailSMTPAppender() {
super();
}
/**
* Create mail session.
*
* #return mail session, may not be null.
*/
protected Session createSession() {
Properties props = new Properties();
props.put("mail.smtps.host", getSMTPHost());
props.put("mail.smtps.auth", "true");
Authenticator auth = null;
if (getSMTPPassword() != null && getSMTPUsername() != null) {
auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getSMTPUsername(),
getSMTPPassword());
}
};
}
session = Session.getInstance(props, auth);
if (getSMTPProtocol() != null) {
session.setProtocolForAddress("rfc822", getSMTPProtocol());
}
if (getSMTPDebug()) {
session.setDebug(getSMTPDebug());
}
return session;
}
/**
* Send the contents of the cyclic buffer as an e-mail message.
*/
protected void sendBuffer() {
try {
MimeBodyPart part = new MimeBodyPart();
StringBuffer sbuf = new StringBuffer();
String t = layout.getHeader();
if (t != null)
sbuf.append(t);
int len = cb.length();
for (int i = 0; i < len; i++) {
LoggingEvent event = cb.get();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append(s[j]);
sbuf.append(Layout.LINE_SEP);
}
}
}
}
t = layout.getFooter();
if (t != null)
sbuf.append(t);
part.setContent(sbuf.toString(), layout.getContentType());
Multipart mp = new MimeMultipart();
mp.addBodyPart(part);
msg.setContent(mp);
msg.setSentDate(new Date());
send(msg);
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}
/**
* Pulled email send stuff i.e. Transport.send()/Transport.sendMessage(). So
* that on required this logic can be enhanced.
*
* #param msg
* Email Message
* #throws MessagingException
*/
protected void send(Message msg) throws MessagingException {
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
try {
t.connect(getSMTPHost(), getSMTPUsername(), getSMTPPassword());
t.sendMessage(msg, msg.getAllRecipients());
} finally {
System.out.println("Response: " + t.getLastServerResponse());
t.close();
}
}
}
How I can instantiate of this appender on my log4j.properties configuration ??
Do you need to programatically add the Appender?
Check the following post
Related
I try to send a mail with following code snippet:
message = new MimeMessage(mailSession);
message.setFrom(from);
message.setRecipients(Message.RecipientType.TO, to);
if(cc != null && cc.length > 0){
message.setRecipients(Message.RecipientType.CC, cc);
}
if(bcc != null && bcc.length > 0){
message.setRecipients(Message.RecipientType.BCC, bcc);
}
if(replyTo != null && replyTo.length > 0){
message.setReplyTo(replyTo);
}
message.setSubject(subject, "utf-8");
message.setSentDate(new java.util.Date());
if (headers != null && !headers.isEmpty()) {
for (String headName : headers.keySet()) {
message.addHeader(headName, headers.get(headName));
}
}
if (Utils.isEmpty(bodyText)) {
bodyText = HTMLHelper.html2text(body);
}
message.setContent(this.buildMessageBody(body, bodyText));
transporter = mailSession.getTransport();
transporter.connect();
transporter.sendMessage(message, message.getAllRecipients());
Bellow following additional methods:
private Multipart buildMessageBody(String body, String bodyText) throws MessagingException {
if(attachments == null || attachments.isEmpty()){
return getAlternativeBodyMimeMultipart(body, bodyText);
}
MimeMultipart multipartRoot = new MimeMultipart("mixed");
BodyPart contentBodyPart = buildContentBodyPart(body, bodyText);
multipartRoot.addBodyPart(contentBodyPart);
List<BodyPart> attachmentParts = buildAttachmentParts();
for(BodyPart singleAttachmentPart : attachmentParts){
multipartRoot.addBodyPart(singleAttachmentPart);
}
return multipartRoot;
}
private List<BodyPart> buildAttachmentParts() {
List<BodyPart> attachmentsParts = new ArrayList<BodyPart>();
for (int i = 0; i < attachments.size(); i++) {
BinaryAttachment attach = attachments.get(i);
MimeBodyPart mbp = new MimeBodyPart();
System.setProperty("mail.mime.encodefilename", "true");
try {
mbp.setDataHandler(new DataHandler(attach));
mbp.setFileName(MimeUtility.encodeText(attach.getName()));
attachmentsParts.add(mbp);
} catch (Exception e) {
logger.error("buildBodyWithAttachment",e);
}
}
return attachmentsParts;
}
private BodyPart buildContentBodyPart(String body, String bodyText) throws MessagingException {
MimeMultipart alternativePart = getAlternativeBodyMimeMultipart(body, bodyText);
BodyPart content = new MimeBodyPart();
content.setContent(alternativePart);
return content;
}
For exemple my sender in "from" variable when I call messages.setFrom(from) have following value:
"M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com"
But when I receive my mail in my mailbox, the send have the following name ...
M. Test ADMINISTRATEURÃÃÃ
From: "M. Test ADMINISTRATEUR???" admin#demo.onmicrosoft.com
I think the problem come from the encoding of "from" which create by:
from = new InternetAddress(sender) and sender is "M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com".
How can I solve this?
You will have to specify the charset - UTF-8 in the InternetAddress constructor.
from = new InternetAddress(email, sender, "UTF-8")
The constructor from JavaMail for the above code is as below.
/**
* Construct an InternetAddress given the address and personal name.
* The address is assumed to be a syntactically valid RFC822 address.
*
* #param address the address in RFC822 format
* #param personal the personal name
* #param charset the MIME charset for the name
* #exception UnsupportedEncodingException if the personal name
* can't be encoded in the given charset
*/
public InternetAddress(String address, String personal, String charset)
throws UnsupportedEncodingException {
this.address = address;
setPersonal(personal, charset);
}
so I searched a lot to send an email throught my app, but without the user having to log in in an email app and send it himself. I would like to just let him write it in an editText and then just press a button and send it to me. So that's what I did: 2 classes for the mail thing, my activity which calls it, add the 3 libraries and the internet permission. What did I do wrong?
Here is where I call the email process :
private View.OnClickListener btnMode1Listener = new
View.OnClickListener() {
#Override
public void onClick(View v) {
suggestionText = entre_suggestion.getText().toString();
Log.i("SendMailActivity", "Send Button Clicked.");
String fromEmail = "fromEmail#gmail.com";
String fromPassword = "frompassword";
String toEmails = "toEmail#gmail.com";
List toEmailList = Arrays.asList(toEmails
.split("\\s*,\\s*"));
Log.i("SendMailActivity", "To List: " + toEmailList);
String emailSubject = "Suggestion";
String emailBody = suggestionText;
new SendMailTask(suggestions.this).execute(fromEmail,
fromPassword, toEmailList, emailSubject, emailBody);
}
};
This is the first class "GMail":
public class GMail {
final String emailPort = "587";// gmail's smtp port
final String smtpAuth = "true";
final String starttls = "true";
final String emailHost = "smtp.gmail.com";
String fromEmail;
String fromPassword;
List toEmailList;
String emailSubject;
String emailBody;
Properties emailProperties;
Session mailSession;
MimeMessage emailMessage;
public GMail() {
}
public GMail(String fromEmail, String fromPassword,
List toEmailList, String emailSubject, String emailBody) {
this.fromEmail = fromEmail;
this.fromPassword = fromPassword;
this.toEmailList = toEmailList;
this.emailSubject = emailSubject;
this.emailBody = emailBody;
emailProperties = System.getProperties();
emailProperties.put("mail.smtp.port", emailPort);
emailProperties.put("mail.smtp.auth", smtpAuth);
emailProperties.put("mail.smtp.starttls.enable", starttls);
Log.i("GMail", "Mail server properties set.");
}
public MimeMessage createEmailMessage() throws AddressException,
MessagingException, UnsupportedEncodingException {
mailSession = Session.getDefaultInstance(emailProperties, null);
emailMessage = new MimeMessage(mailSession);
emailMessage.setFrom(new InternetAddress(fromEmail, fromEmail));
for (Object toEmail : toEmailList) {
Log.i("GMail","toEmail: "+toEmail);
emailMessage.addRecipient(Message.RecipientType.TO,
new InternetAddress((String) toEmail));
}
emailMessage.setSubject(emailSubject);
emailMessage.setContent(emailBody, "text/html");// for a html email
// emailMessage.setText(emailBody);// for a text email
Log.i("GMail", "Email Message created.");
return emailMessage;
}
public void sendEmail() throws AddressException, MessagingException {
Transport transport = mailSession.getTransport("smtp");
transport.connect(emailHost, fromEmail, fromPassword);
Log.i("GMail","allrecipients: "+emailMessage.getAllRecipients());
transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
transport.close();
Log.i("GMail", "Email sent successfully.");
}
}
And this is the second class "SendMailtask":
public class SendMailTask extends AsyncTask {
private ProgressDialog statusDialog;
private Activity sendMailActivity;
public SendMailTask(Activity activity) {
sendMailActivity = activity;
}
protected void onPreExecute() {
statusDialog = new ProgressDialog(sendMailActivity);
statusDialog.setMessage("Getting ready...");
statusDialog.setIndeterminate(false);
statusDialog.setCancelable(false);
statusDialog.show();
}
#Override
protected Object doInBackground(Object... args) {
try {
Log.i("SendMailTask", "About to instantiate GMail...");
publishProgress("Processing input....");
GMail androidEmail = new GMail(args[0].toString(),
args[1].toString(), (List) args[2], args[3].toString(),
args[4].toString());
publishProgress("Preparing mail message....");
androidEmail.createEmailMessage();
publishProgress("Sending email....");
androidEmail.sendEmail();
publishProgress("Email Sent.");
Log.i("SendMailTask", "Mail Sent.");
} catch (Exception e) {
publishProgress(e.getMessage());
Log.e("SendMailTask", e.getMessage(), e);
}
return null;
}
#Override
public void onProgressUpdate(Object... values) {
statusDialog.setMessage(values[0].toString());
}
#Override
public void onPostExecute(Object result) {
statusDialog.dismiss();
}
}
And finally, the 3 librairies I added:
compile files('libs/activation.jar')
compile files('libs/additionnal.jar')
compile files('libs/mail.jar')
So yeah, I searched a lot and didn't find how to debug it. I tried a lot of different ways but it never sent the email. I just want to be clear that I don't want to open the mail app, I want the email to be sent without the user having to do something.
package com.auto.smartautomates.smartautomates.Helpers;
import com.crashlytics.android.Crashlytics;
import java.util.Calendar;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
/**
* Created by sardar.khan on 6/8/2017.
*/
public class MailService {
// public static final String MAIL_SERVER = "localhost";
private String toList;
private String ccList;
private String bccList;
private String subject;
final private static String SMTP_SERVER = "smtp.gmail.com";
private String from;
private String txtBody;
private String htmlBody;
private String replyToList;
private boolean authenticationRequired = false;
public MailService(String from, String toList, String subject, String txtBody, String htmlBody) {
this.txtBody = txtBody;
this.htmlBody = htmlBody;
this.subject = subject;
this.from = from;
this.toList = toList;
this.ccList = null;
this.bccList = null;
this.replyToList = null;
this.authenticationRequired = true;
}
public void sendAuthenticated() throws AddressException, MessagingException {
authenticationRequired = true;
send();
}
/**
* Send an e-mail
*
* #throws MessagingException
* #throws AddressException
*/
public void send() throws AddressException, MessagingException {
Properties props = new Properties();
// set the host smtp address
props.put("mail.smtp.host", SMTP_SERVER);
props.put("mail.user", from);
props.put("mail.smtp.starttls.enable", "true"); // needed for gmail
props.put("mail.smtp.auth", "true"); // needed for gmail
props.put("mail.smtp.port", "587"); // gmail smtp port 587 default gmail
/*Authenticator auth = new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("mobile#mydomain.com", "mypassword");
}
};*/
Session session;
if (authenticationRequired) {
Authenticator auth = new SMTPAuthenticator();
props.put("mail.smtp.auth", "true");
session = Session.getDefaultInstance(props, auth);
} else {
session = Session.getDefaultInstance(props, null);
}
// get the default session
session.setDebug(true);
// create message
Message msg = new javax.mail.internet.MimeMessage(session);
// set from and to address
try {
msg.setFrom(new InternetAddress(from, from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from,from)});
} catch (Exception e) {
Crashlytics.logException(e);
msg.setFrom(new InternetAddress(from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from)});
}
// set send date
msg.setSentDate(Calendar.getInstance().getTime());
// parse the recipients TO address
java.util.StringTokenizer st = new java.util.StringTokenizer(toList, ",");
int numberOfRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressTo = new javax.mail.internet.InternetAddress[numberOfRecipients];
int i = 0;
while (st.hasMoreTokens()) {
addressTo[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo);
// parse the replyTo addresses
if (replyToList != null && !"".equals(replyToList)) {
st = new java.util.StringTokenizer(replyToList, ",");
int numberOfReplyTos = st.countTokens();
javax.mail.internet.InternetAddress[] addressReplyTo = new javax.mail.internet.InternetAddress[numberOfReplyTos];
i = 0;
while (st.hasMoreTokens()) {
addressReplyTo[i++] = new javax.mail.internet.InternetAddress(
st.nextToken());
}
msg.setReplyTo(addressReplyTo);
}
// parse the recipients CC address
if (ccList != null && !"".equals(ccList)) {
st = new java.util.StringTokenizer(ccList, ",");
int numberOfCCRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressCC = new javax.mail.internet.InternetAddress[numberOfCCRecipients];
i = 0;
while (st.hasMoreTokens()) {
addressCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.CC, addressCC);
}
// parse the recipients BCC address
if (bccList != null && !"".equals(bccList)) {
st = new java.util.StringTokenizer(bccList, ",");
int numberOfBCCRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressBCC = new javax.mail.internet.InternetAddress[numberOfBCCRecipients];
i = 0;
while (st.hasMoreTokens()) {
addressBCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.BCC, addressBCC);
}
// set header
msg.addHeader("X-Mailer", "MyAppMailer");
msg.addHeader("Precedence", "bulk");
// setting the subject and content type
msg.setSubject(subject);
Multipart mp = new MimeMultipart("related");
// set body message
MimeBodyPart bodyMsg = new MimeBodyPart();
bodyMsg.setText(txtBody, "iso-8859-1");
bodyMsg.setContent(htmlBody, "text/html");
mp.addBodyPart(bodyMsg);
msg.setContent(mp);
// send it
try {
javax.mail.Transport.send(msg);
} catch (Exception e) {
Crashlytics.logException(e);
e.printStackTrace();
}
}
/**
* SimpleAuthenticator is used to do simple authentication when the SMTP
* server requires it.
*/
private static class SMTPAuthenticator extends javax.mail.Authenticator {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
String username = "someEmail#gmail.com";
String password ="yourPassword";
return new PasswordAuthentication(username, password);
}
}
public String getToList() {
return toList;
}
public void setToList(String toList) {
this.toList = toList;
}
public String getCcList() {
return ccList;
}
public void setCcList(String ccList) {
this.ccList = ccList;
}
public String getBccList() {
return bccList;
}
public void setBccList(String bccList) {
this.bccList = bccList;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setFrom(String from) {
this.from = from;
}
public void setTxtBody(String body) {
this.txtBody = body;
}
public void setHtmlBody(String body) {
this.htmlBody = body;
}
public String getReplyToList() {
return replyToList;
}
public void setReplyToList(String replyToList) {
this.replyToList = replyToList;
}
public boolean isAuthenticationRequired() {
return authenticationRequired;
}
public void setAuthenticationRequired(boolean authenticationRequired) {
this.authenticationRequired = authenticationRequired;
}
}
In your account settings, allow smtp, and allow unsafe apps
http://pastie.org/4185959
I've used this code to make a mailing app that takes in authenticating parameters within the code. Sending the plain mail alone works fine, but adding the attachment is an issue, commenting out the line m.addAttachment() makes the mail send successfully even though I pass the path of a file correctly. Here's the code I use:
class MailSender extends AsyncTask<Void, Integer, Integer>
{
ProgressDialog pd = null;
/* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd = new ProgressDialog(MailSenderActivity.this);
pd.setTitle("Uploading...");
pd.setMessage("Uploading logs. Please wait...");
pd.setCancelable(false);
pd.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected Integer doInBackground(Void... params) {
Mail m = new Mail("from_mail#gmail.com", "password");
String toAddresses = "to_mail#gmail.com";
m.setToAddresses(toAddresses);
m.setFromAddress("from_mail#gmail.com");
m.setMailSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setMailBody("Email body.");
/*try {
ZipUtility.zipDirectory(new File("/mnt/sdcard/logs/"), new File("/mnt/sdcard/logs.zip"));
} catch (IOException e1) {
Log.e("MailApp", "Could not zip folder", e1);
}*/
try {
m.addAttachment("/mnt/sdcard/Pictures/test.jpg");
if (m.send()) {
System.out.println("Message sent");
return 1;
} else {
return 2;
}
} catch (Exception e) {
Log.e("MailApp", "Could not send email", e);
}
return 3;
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
if(result==1)
Toast.makeText(MailSenderActivity.this,
"Email was sent successfully.", Toast.LENGTH_LONG)
.show();
else if(result==2)
Toast.makeText(MailSenderActivity.this,
"Email was not sent.", Toast.LENGTH_LONG).show();
else if(result==3)
Toast.makeText(MailSenderActivity.this,
"There was a problem sending the email.",
Toast.LENGTH_LONG).show();
}
And the Mail.java class
public class Mail extends javax.mail.Authenticator {
private Multipart attachements;
private String fromAddress = "";
private String accountEmail = "";
private String accountPassword = "";
private String smtpHost = "smtp.gmail.com";
private String smtpPort = "465"; // 465,587
private String toAddresses = "";
private String mailSubject = "";
private String mailBody = "";
public Mail() {
attachements = new MimeMultipart();
}
public Mail(String user, String pass) {
this();
accountEmail = user;
accountPassword = pass;
}
public boolean send() throws Exception {
Properties props = new Properties();
//props.put("mail.smtp.user", d_email);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", smtpPort);
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
try {
Session session = Session.getInstance(props, this);
session.setDebug(true);
MimeMessage msg = new MimeMessage(session);
// create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
//fill message
messageBodyPart.setText(mailBody);
// add to multipart
attachements.addBodyPart(messageBodyPart);
//msg.setText(mailBody);
msg.setSubject(mailSubject);
msg.setFrom(new InternetAddress(fromAddress));
msg.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(toAddresses));
msg.setContent(attachements);
Transport transport = session.getTransport("smtps");
transport.connect(smtpHost, 465, accountEmail, accountPassword);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return true;
} catch (Exception e) {
return false;
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
attachements.addBodyPart(messageBodyPart);
}
private String getFormattedDate(Date date)
{
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd-MMM-yyyy hh:mm:ss a");
return sdf.format(date);
}
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(accountEmail, accountPassword);
}
/**
* Gets the fromAddress.
*
* #return <tt> the fromAddress.</tt>
*/
public String getFromAddress() {
return fromAddress;
}
/**
* Sets the fromAddress.
*
* #param fromAddress <tt> the fromAddress to set.</tt>
*/
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
/**
* Gets the toAddresses.
*
* #return <tt> the toAddresses.</tt>
*/
public String getToAddresses() {
return toAddresses;
}
/**
* Sets the toAddresses.
*
* #param toAddresses <tt> the toAddresses to set.</tt>
*/
public void setToAddresses(String toAddresses) {
this.toAddresses = toAddresses;
}
/**
* Gets the mailSubject.
*
* #return <tt> the mailSubject.</tt>
*/
public String getMailSubject() {
return mailSubject;
}
/**
* Sets the mailSubject.
*
* #param mailSubject <tt> the mailSubject to set.</tt>
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* Gets the mailBody.
*
* #return <tt> the mailBody.</tt>
*/
public String getMailBody() {
return mailBody;
}
/**
* Sets the mailBody.
*
* #param mailBody <tt> the mailBody to set.</tt>
*/
public void setMailBody(String mailBody) {
this.mailBody = mailBody;
}
}
As you can see, the addAttachment method only takes in a string, specifically the file path. I've passed the file path directly, as I have a file named 'test.jpg' in my Pictures folder, but I'm still getting this message:
java.io.FileNotFoundException: /mnt/sdcard/Pictures/test.jpg: open failed: EACCES (Permission denied)
I've added permissions for both the INTERNET and EXTERNAL_DATA_STORAGE, so that's not the issue. It seems as though for some reason I cannot access this file within the Pictures folder.
Here's the location of the file within Amaze:
http://i.imgur.com/nbsWzsb.png
I know this issue is old, but I didn't find any solution for SimpleMailMessage with properties added in the class and not in the xml. There is no exeption after my app starts, its simply not sending mail. The method CustomMailDeliveryImpl.sendMail() is trigered from Controlller. I cant find a mistake.
#Component("CustomMailDelivery")
public class CustomMailDeliveryImpl implements CustomMailDelivery {
protected static Logger logger = Logger.getLogger(CustomMailDeliveryImpl.class);
private EmployeeService employeeService;
private String username = "* * *#gmail.com";
private String password = "* * *";
private JavaMailSenderImpl sender = new JavaMailSenderImpl();
#Autowired
public void setSender(JavaMailSenderImpl sender) {
this.sender = sender;
}
#Autowired
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* #param from - must contain address of sender,
* #param to - must contain address of target,
* #param subject - must be included with short description,
* #param body - main message of mail.
* #throws RuntimeException if any param is empty.
*/
public void sendMail(String from, String to, String subject, String body) {
// selecting settings from DB
SystemSettingsModel settingsModel = employeeService.getSettingsByName("default");
// defining settings
sender.setHost(settingsModel.getSmtpServerAddress());
sender.setPort(settingsModel.getSmtpServerPort());
sender.setUsername(username);
sender.setPassword(password);
// defining SMTP properties
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.debug", "1");
Session session = Session.getDefaultInstance(properties, null);
sender.setSession(session);
// initiating mail
SimpleMailMessage simpleMessage = new SimpleMailMessage();
try {
if (from != null && to != null) {
if (subject != null && body != null) {
simpleMessage.setFrom(from);
simpleMessage.setTo(to);
simpleMessage.setSubject(subject);
simpleMessage.setText(body);
sender.send(simpleMessage);
logger.debug("Mail has been sent successfully");
} else {
throw new MessagingException("Subject and message of mail is empty!");
}
} else {
throw new MessagingException("Address of object and target is empty!");
}
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Any help appreciated !!!!
I finally managed to overcome this issue and I did found the solution! With this way? you can pass properties from page configuration or DAO Service!
#Component("CustomMailDeliveryImpl")
public class CustomMailDeliveryImpl implements CustomMailDelivery {
private EmployeeService employeeService;
private Transport transport;
private String username = "***#gmail.com";
private String password = "***";
private SystemSettingsModel settingsModel;
private Session session;
private MimeMessage message;
private InternetAddress fromAddress, toAddress;
private Properties properties;
#Autowired
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public void sendMail(String from, String to, String subject, String body) throws SendFailedException {
settingsModel = employeeService.getSettingsByName("default");
// defining properties
properties = new Properties();
properties.put("mail.smtp.host", settingsModel.getSmtpServerAddress());
properties.put("mail.smtp.port", settingsModel.getSmtpServerPort());
properties.put("mail.smtp.user", username);
properties.put("mail.smtp.password", password);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
// InternetAddress initialisation
try {
fromAddress = new InternetAddress(from);
toAddress = new InternetAddress(to);
// new Authenticator session
session = (javax.mail.Session) Session.getDefaultInstance(properties, null);
} catch (AddressException e) {
throw new RuntimeException();
}
// executing mail sending
try {
if (from != null && to != null) {
if (subject != null && body != null) {
// defining message
message = new MimeMessage(session);
message.setFrom(fromAddress);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(subject);
message.setText(body);
message.setSentDate(new Date());
message.setHeader("MIME-Version" , "1.0" );
message.setHeader("Content-Type" , "text/html" );
// Transport initialisation
if (transport == null) {
transport = session.getTransport("smtp");
if (!transport.isConnected())
transport.connect(settingsModel.getSmtpServerAddress(),
settingsModel.getSmtpServerPort(), username, password);
}
transport.sendMessage(message, message.getAllRecipients());
} else {
throw new MessagingException("Subject and message of mail is empty!");
}
} else {
throw new MessagingException("Address and target of mail is empty!");
}
} catch (MessagingException e) {
e.printStackTrace();
throw new RuntimeException();
} finally {
if (transport != null) try {
transport.close();
} catch (MessagingException ignore) {
}
}
}
}
It's working just perfect!!
I want to modify or remove the "Message-ID" header when replying to an email with Javamail. After some research I found out I need to create a custom class that extends MimeMessage. Here is the class that I have created.
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
class MyMessage extends MimeMessage
{
public MyMessage(Session session)
{
super(session);
}
#Override
protected void updateMessageID() throws MessagingException {
removeHeader("Message-Id");
}
}
The code below is related to fetching the messages
public List<EmailSenderInfo> checkEmail() throws Exception
{
String host = "HOST";
String username = "MYUSERNAME";
String password = "MYPASS";
List<EmailSenderInfo> emailSenderList = new ArrayList<EmailSenderInfo>();
Properties properties = System.getProperties();
properties.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("imaps");
store.connect(host, username, password);
/*
* Folder[] f = store.getDefaultFolder().list(); for (Folder fd : f)
* System.out.println(">> " + fd.getName());
*/
Folder folder = store.getFolder("INBOX");
if (!folder.exists())
{
System.out.println("No INBOX...");
System.exit(0);
}
folder.open(Folder.READ_WRITE);
Message[] msg = folder.getMessages();
if (msg.length < 1)
{
System.out.println("No new messages!");
throw new Exception("No new messages!");
}
for (int i = 0; i < msg.length; i++)
{
if (!msg[i].isSet(Flag.SEEN))
{
EmailSenderInfo emailSenderInfo = new EmailSenderInfo();
emailSenderInfo.message = msg[i];
System.out.println("------------ Message " + (i + 1) + " ------------");
// String from = InternetAddress.toString(msg[i].getFrom());
Address[] fromArray = msg[i].getFrom();
InternetAddress fromInternetAddress = (InternetAddress) fromArray[0];
String from = fromInternetAddress.getAddress();
String fromName = fromInternetAddress.getPersonal();
if (fromName != null)
{
emailSenderInfo.fromName = fromName;
}
if (from != null)
{
// System.out.println("From: " + from);
emailSenderInfo.from = from;
}
// String replyTo = InternetAddress.toString(msg[i].getReplyTo());
Address[] replyToArray = msg[i].getFrom();
InternetAddress ReplyToInternetAddress = (InternetAddress) replyToArray[0];
String replyTo = ReplyToInternetAddress.getAddress();
String replyToName = ReplyToInternetAddress.getPersonal();
if (replyTo != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyTo = replyTo;
}
if (replyToName != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyToName = replyToName;
}
String to = InternetAddress.toString(msg[i].getRecipients(Message.RecipientType.TO));
if (to != null)
{
// System.out.println("To: " + to);
emailSenderInfo.to = to;
}
String subject = msg[i].getSubject();
if (subject != null)
{
// System.out.println("Subject: " + subject);
emailSenderInfo.subject = subject;
}
Date sentDate = msg[i].getSentDate();
if (sentDate != null)
{
System.out.println("Sent: " + sentDate);
emailSenderInfo.sentDate = sentDate;
}
String bodyHtml = "";
// get content
Multipart multipart = (Multipart) msg[i].getContent();
for (int x = 0; x < multipart.getCount(); x++)
{
BodyPart bodyPart = multipart.getBodyPart(x);
String disposition = bodyPart.getDisposition();
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
// dealing with attachments only
System.out.println("Mail has some attachment : ");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
System.out.println("ddddd: " + bodyPart.getContent().toString());
}
else
{
String classType = bodyPart.getContent().getClass().toString();
if (classType.contains("java.lang.String"))
{
bodyHtml = bodyPart.getContent().toString();
}
else if (classType.contains("javax.mail.internet.MimeMultipart"))
{
MimeMultipart bodyContent = (MimeMultipart) bodyPart.getContent();
for (int b = 0; b < bodyContent.getCount(); b++)
{
IMAPBodyPart imapBody = (IMAPBodyPart) bodyContent.getBodyPart(b);
System.out.println("1: " + imapBody.getContent());
bodyHtml = imapBody.getContent().toString();
// System.out.println("2: " + bodyContent.getBodyPart(b));
// System.out.println("3: " + bodyPart.getContent().toString());
}
}
}
emailSenderInfo.bodyHtml = bodyHtml;
}
MyMessage reply = (MyMessage) msg[i].reply(false);
emailSenderInfo.reply = reply;
// reply.setFrom(msg[i].getFrom()[0]);
MimeMessage orig = (MimeMessage) msg[i];
StringBuffer buffer = new StringBuffer("Thanks\n\n");
if (orig.isMimeType("text/plain"))
{
String content = (String) orig.getContent();
StringReader contentReader = new StringReader(content);
BufferedReader br = new BufferedReader(contentReader);
String contentLine;
while ((contentLine = br.readLine()) != null)
{
buffer.append("> ");
buffer.append(contentLine);
buffer.append("\r\n");
}
}
// Set the reply content
// reply.setText(buffer.toString());
// emailSenderInfo.reply = reply;
emailSenderList.add(emailSenderInfo);
// System.out.println();
}// end if unread
}
folder.close(true);
store.close();
return emailSenderList;
}
I have two methods in my program. One of them checks mail and another one which replies to emails.
Message reply = msg[i].reply(false);
"reply" gets passed to this method along with other parameters.
public void sendReply(String from, String replyTo, Message reply, String messageReply, Boolean attachment) throws Exception
{
String host = "MYHOST";
String username = "MYUSERNAME";
String pass = "MYPASSWORD";
Properties props = System.getProperties();
props.put("mail.smtp.starttls.enable", "true"); // added this line
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", username);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage mimeReply = (MimeMessage) reply;
mimeReply.setFrom((Address) InternetAddress.parse(from)[0]);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(messageReply, "text/html");
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
if (attachment)
{
messageBodyPart = new MimeBodyPart();
String filename = "test.jpg";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
mimeReply.setContent(multipart);
Transport transport = session.getTransport("smtp");
transport.connect(host, username, pass);
transport.sendMessage(mimeReply, InternetAddress.parse(replyTo));
transport.close();
System.out.println("Message Sent!");
}
I have to use the MyMessage class in order to remove the "Message-ID" header. I have tried the following
MyMessage mimeReply = (MyMessage) reply;
But I get the following error in runtime
java.lang.ClassCastException: javax.mail.internet.MimeMessage cannot be cast to javamailer.MyMessage
How can use "MyMessage" class so I can remove the "Message-ID" header with the reply message?
You can try the following:
When replying to an email:
When you create a message create, right now it should be like:
MimeMessage msg = new MimeMessage(session);
change it to,
MyMessage msg = new MyMessage(session);
When checking email you don't need to remove the header as that message is already in the mailbox, what I think you need to do is when replying to a mail at that instance for the name mail instantiate like :
MyMessage msg = new MyMessage(session);
msg.updateMessageID();
Since you are using reference to existing message:
You can do something like:
Create a new constructor:
public MyMessage (MimeMessage message) {
super(message);
}
When replying:
MyMessage mimeReply = new MyMessage(reply);
mimeReply.updateMessageID();
Then send the mimeReply NOT reply.