I have a bizarre problem that I can't seem to get a handle on. :(
I have a Web based application that sends emails. It does so by connecting a Windows based SMTP server that was setup on a local network. This SMTP server does not require a username or a passord from my code in order to send the emails. Most of the day and sometimes most of the week everything works beautifully, the emails are sent and users are happy. Then out of nowhere and for no apparent reason I start seeing the Exception in my log that says:
javax.mail.AuthenticationFailedException: failed to connect, no password specified?
at javax.mail.Service.connect(Service.java:398)
at javax.mail.Service.connect(Service.java:245)
at javax.mail.Service.connect(Service.java:194)
at javax.mail.Transport.send0(Transport.java:253)
at javax.mail.Transport.send(Transport.java:124)
I upgraded my java mail jar to the latest version hich I guess is called javax.mail.far these days. We're running Tomcat 7, and Windows Server 2008R2 and the mail server is a Microsoft one.
I don't understand why this works sometimes but then stops for no apparent reason. But what I really would like to do is fix this issue so that it does not appear again. If any one has seen something like this before and has any ideas I would love to hear them. Here's the Java code that sends the emails:
Properties props = System.getProperties();
if (mailhost != null)
props.setProperty("mail.smtp.host", mailhost);
// Get a Session object
Session session = Session.getDefaultInstance(props);
// Output the email in the log window
session.setDebug(true);
// construct the message
Message msg = new MimeMessage(session);
if (from != null)
msg.setFrom(new InternetAddress(from));
else
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email.getTo(), false));
if ((email.getCc() != null) && (email.getCc().length() > 0))
msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(email.getCc(), false));
if ((email.getBcc() != null) && (email.getBcc().length() > 0))
msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(email.getBcc(), false));
msg.setSubject(email.getSubject());
// Check if Attachment file exists
if ((attachmentFile != null) && (attachmentFile.getFileName() != null) &&
(attachmentFile.getFileName().length() > 0) )
{
MimeMultipart multipart = new MimeMultipart();
// Set the Message Text
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(email.getBody());
multipart.addBodyPart(messageBodyPart);
// Set the Message Attachment
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
DataSource ds = new ByteArrayDataSource(attachmentFile.getInputStream(), attachmentFile.getContentType());
attachmentBodyPart.setDataHandler(new DataHandler(ds));
attachmentBodyPart.setFileName(attachmentFile.getFileName());
multipart.addBodyPart(attachmentBodyPart);
// If we also have a PDF attachment
if (PDFAtch != null)
{
MimeBodyPart pdfAttachmentBodyPart = new MimeBodyPart();
ds = new ByteArrayDataSource(PDFAtch.getAttachment(), "application/pdf");
pdfAttachmentBodyPart.setDataHandler(new DataHandler(ds));
pdfAttachmentBodyPart.setFileName(PDFAtch.getFilename());
multipart.addBodyPart(pdfAttachmentBodyPart);
}
// Put parts in message
msg.setContent(multipart);
}
else if (PDFAtch != null)
{
MimeMultipart multipart = new MimeMultipart();
// Set the Message Text
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(email.getBody());
multipart.addBodyPart(messageBodyPart);
MimeBodyPart pdfAttachmentBodyPart = new MimeBodyPart();
DataSource ds = new ByteArrayDataSource(PDFAtch.getAttachment(), "application/pdf");
pdfAttachmentBodyPart.setDataHandler(new DataHandler(ds));
pdfAttachmentBodyPart.setFileName(PDFAtch.getFilename());
multipart.addBodyPart(pdfAttachmentBodyPart);
msg.setContent(multipart);
}
else
msg.setText(email.getBody());
msg.setHeader("X-Mailer", "EWarranty MailSender");
msg.setSentDate(email.getDateSent());
// send the thing off
Transport.send(msg);
logger.debug("Message sent successfully to "+email.getTo());
Thank you in advance for any and all help.
Posting the answer for those who may run into a similar problem.
Setting the following 2 properties seems to have done the trick, at least so far. :)
props.setProperty("mail.smtp.auth", "false");
props.put("mail.smtp.port", "25"); // Default port
I spoke to my email admin and he told me that the main port that our email server uses is in fact 25.
I did not change the way I create the session. At least not yet. BTW that link that Bill provided is an outstanding read and I highly recommend clicking on it and reading it.
Thanks everyone
Change Session.getDefaultInstance to Session.getInstance and see if that helps.
I've got the same problem and finally I've solved it.
The main problem is using system global properties:
Properties props = System.getProperties();
Other thread in your process can set mail.smtp.auth to true.
You should just use you own local properties:
Properties properties = new Properties();
Related
I want to include attachments when email is sent to a recipient. I have been able to set and get the attachments but when the attachFile method is called from the Javaxmail I get an error.
This code is written in Java using the javax library.
Everything seems fine, but fails. I've tried adding encoding as well but same results.
This code fails when the attachFile method is called.
attachPart.attachFile(f); // fails here...
try {
Message msg = new MimeMessage(propsSess);
msg.setFrom(new InternetAddress(this.defaultSenderAddress));
setRecipient(msg, this.sendTo, "to");
msg.setSubject(this.subject);
msg.setContent(this.bodyHtml, "text/html");
msg.setHeader("X-Mailer", "Java Agent");
msg.setSentDate(new Date());
if (!this.bodyAttach.isEmpty()) {
BodyPart messageText = new MimeBodyPart();
messageText.setText(this.bodyHtml);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageText);
// adds attachments
for (int index = 0; index < this.bodyAttach.size(); index++) {
MimeBodyPart attachPart = new MimeBodyPart();
try {
System.out.println(this.bodyAttach.get(index)); // shows only 1st attachments
File f = new File(this.bodyAttach.get(index));
attachPart.attachFile(f); // fails here...
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(attachPart);
}
// sets the multi-part as e-mail's content
msg.setContent(multipart);
}
SMTPTransport transport = (SMTPTransport) propsSess.getTransport("smtp");
transport.connect(this.smtpServerAddress, null, null);
if (transport.isConnected()) {
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
this.processMessage.add("success");
}
} catch (Exception e) {
this.processMessage.add(databaseTitle + ": SmtpMail bean: Message or SMTPTransport error");
return false;
}
javax.mail is something of a land mine on Domino. It's kind of present, by way of "mail.jar" in the "ndext" directory as well as the com.ibm.designer.lib.javamail plugin in OSGi land, but that is version 1.3 of the spec. The method you're trying to use there was, unfortunately, added in 1.4.
You may be able to get around it by adding a jar for a newer version of javax.mail+its implementation to your NSF, but I haven't tried that so I can't say for sure. That may be what you're already trying anyway, to get access to the classes. You could also try putting this code in an OSGi plugin and embedding the javax.mail jar inside that or bringing it along as a version-range-constricted external OSGi plugin.
You could alternatively use the Notes API to send email, though then you'd be using the Domino server to route the email and not a custom SMTP server (unless Domino happens to be configured to route through that server anyway).
I tried in many ways to get the reply in same thread using outlook account and javamail api but iam not able to get reply in same thread instead iam getting as attachment.
I tried to copy whole content and save in current message even then iam getting as attachment, also tried to change the content disposition as inline still it didn't work
you can find the code below which i had tried.
Properties properties = new Properties();
Session emailSession = Session.getDefaultInstance(properties,null);
store = emailSession.getStore("imaps");
store.connect(host,mailbox_username, mailbox_password);
folder = store.getFolder("Inbox");
folder.open(Folder.READ_WRITE);
Message[] unreadMessages = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN),false));
if(unreadMessages.size()>0)
{
for (int i = 0; i < unreadMessages.length; i++)
{
log.info("retriving message "+(i+1))
Message message = unreadMessages[i]
Address[] froms = message.getFrom();
String senderEmailAddress =(froms[0]).getAddress();
if(senderEmailAddress.endsWith("#gmail.com"))
{
subject = message.getSubject()
log.info(message.getSubject())
}
else
{ //reply to same mail here we need to reply to the message
Message message2 = new MimeMessage(emailSession);
message2= (MimeMessage) message.reply(false);
message2.setSubject("RE: " + message.getSubject());
//message2.setFrom(new InternetAddress(from));
message2.setReplyTo(message.getReplyTo());
message2.addRecipient(Message.RecipientType.TO, new InternetAddress(senderEmailAddress));
BodyPart messageBodyPart = new MimeBodyPart();
content = "some reply message"
//multipart.addBodyPart(content);
messageBodyPart.setText(content);
Multipart multipart = new MimeMultipart("related");
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
//messageBodyPart.setDataHandler(message.getDataHandler());
//bodyPart.setDataHandler(new DataHandler(ds));
//messageBodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg");
//messageBodyPart.setHeader("Content-ID", "<image>");
//messageBodyPart.setHeader("Content-Disposition", "inline");
//messageBodyPart.addBodyPart(bodyPart);
//msg.setContent(content);
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
messageBodyPart.setContent(message, "message/rfc822");
messageBodyPart.setDataHandler(message.getDataHandler());
// Add part to multi part
multipart.addBodyPart(messageBodyPart);
// Associate multi-part with message
message2.setContent(multipart);
Transport t = emailSession.getTransport("smtp");
try {
t.connect(mailbox_username, mailbox_password);
t.sendMessage(message2, message2.getAllRecipients());
} finally {
t.close();
}
}
}
}
"inline" vs. "attachment" is just advice for the mail reader. Many ignore the device, or aren't capable of displaying all content types inline.
If you want the text of the original message to appear in the body of the reply message (e.g., indented with ">"), you need to extract the original text and reformat it appropriately, adding it to the text of the reply, then set that new String as the content of the reply message.
I would like to fetch recent, unread emails with a specific subject in a particular folder from my gmail account. I am using JavaMail API as below but it returns 0 results. However if I just use subjectTerm alone, I see results. Please let me know where am I going wrong. Thank you.
Please note that I used messages[0] below instead of looping through messages array for code simplicity to paste it here.
public void openMailBox(String hostname, String username, String password, String folderName, String subject) throws MessagingException, GeneralSecurityException, IOException{
props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imaps.host", "imap.gmail.com");
props.setProperty("mail.imaps.port", "993");
props.setProperty("mail.imaps.ssl.enable", "true");
props.put("mail.imaps.ssl.socketFactory", new MailSSLSocketFactory());
session = Session.getInstance(props);
store = session.getStore();
store.connect(username, password);
folder = store.getFolder(folderName);
folder.open(Folder.READ_ONLY);
messages = folder.search(getSearchTerm(subject));
if (messages[0].isMimeType("multipart/*")){
Multipart multipart = (Multipart) messages[0].getContent();
for(int i=0;i<multipart.getCount();i++) {
BodyPart bodyPart = multipart.getBodyPart(0);
if (bodyPart.isMimeType("text/*")) {
msg = msg+bodyPart.getContent().toString();
}
}
}else{
msg = messages[0].getContent().toString();
}
System.out.println(msg);
folder.close(true);
store.close();
}
public SearchTerm getSearchTerm(String subject){
subjectTerm = new SubjectTerm(subject);
unseenFlagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
recentFlagTerm; = new FlagTerm(new Flags(Flags.Flag.RECENT), true);
return new AndTerm(subjectTerm, new AndTerm(unseenFlagTerm, recentFlagTerm));
}
}
What mail server are you using?
Some mail servers don't implement the RECENT flag in any useful way, so messages might not be marked RECENT. Try leaving out the RECENT term and see if you get more results.
If that doesn't help, add code to dump out the flags for all messages and then post the JavaMail debug output that shows the flags for all messages along with the search request and response.
Note also that some IMAP servers don't fully or correctly implement the SEARCH command and so can't handle the kind of search you're doing.
Finally, note that you don't need to set the socketFactory property unless you're using MailSSLSocketFactory in a more interesting way than you've show in your example code above.
Ok so I'm having to alter some old code from another dev that he sent up for sending emails from our app with Java Mail. This has worked fine for a long time but now we are required to send pdf attachments as well.
So basically below, assume there is an object "mail" that has getters for the text and html messages as well as now a getter for the pdf filename to load from the filesystem and attach to the mail.
I've altered the below code where marked, so if there is a pdf to attach, load from filesystem and attach. I've tried to use the same structure as the previous code, although I suspect its not all required?
Multipart mp = new MimeMultipart("alternative");
// Create a "text" Multipart message
BodyPart textPart = new MimeBodyPart();
textPart.setContent(mail.getText(), "text/plain");
mp.addBodyPart(textPart);
// Create a "HTML" Multipart message
Multipart htmlContent = new MimeMultipart("related");
BodyPart htmlPage = new MimeBodyPart();
htmlPage.setContent(mail.getHtml(), "text/html; charset=UTF-8");
htmlContent.addBodyPart(htmlPage);
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(htmlContent);
mp.addBodyPart(htmlPart);
// NEW CODE STARTS HERE
if(StringUtils.isNotBlank(mail.getPdfAttachmentFileName())) {
Multipart pdfContent = new MimeMultipart("mixed"); //<---- this appears to be an issue???
BodyPart pdfPage = new MimeBodyPart();
File file = new File(uploadDir + "/" + mail.getPdfAttachmentFileName());
DataSource dataSource = new ByteArrayDataSource(new FileInputStream(file), "application/pdf");
pdfPage.setDataHandler(new DataHandler(dataSource));
pdfPage.setFileName(mail.getPdfAttachmentFileName());
pdfContent.addBodyPart(pdfPage);
BodyPart pdfPart = new MimeBodyPart();
pdfPart.setContent(pdfContent);
mp.addBodyPart(pdfPart);
}
// NEW CODE ENDS HERE
mimeMessage.setContent(mp);
At any rate, the above works, sort of. There are no errors or exceptions and the message gets sent. BUT the attachment doesn't appear depending on which email client you recieve the mail with.
With the code as above, Outlook receives the message as readable and the attachment is visible and downloadable. This is perfect. BUT in GMail, the message is still readable, the paperclip appears to indicate there is an attachment, but there is no attachment to download?
If you switch the `Multipart pdfContent = new MimeMultipart("mixed");' to be "related" rather than "mixed" the exact opposite is true. GMail receives it perfectly but Outlook only gets the message and paperclip, no actual attachment.
Obviously we need to be sending emails to our customers with no knowledge of their email client used to open them! Obviously I'm a novice at Java Mail so have simply copied suggested code but this isn't gelling well with our existing code!
Any ideas how to alter the above to make it completely email client independant?
Ok turns out Spring has a helper class to hide all this mess away from you.
I've refactored all of the above code into the following and it works great;
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
message.setTo(mail.getTo());
message.setFrom(mail.getFrom());
message.setSubject(mail.getSubject());
message.setText(mail.getText(), mail.getHtml());
if(StringUtils.isNotBlank(mail.getPdfAttachmentFileName())) {
File file = new File(uploadDir + "/" + mail.getPdfAttachmentFileName());
DataSource dataSource = new ByteArrayDataSource(new FileInputStream(file), "application/pdf");
message.addAttachment(mail.getPdfAttachmentFileName(), dataSource);
}
Using the code below i can send an email written in non-english and although the subject appears correctly the body appears as gibberish.
Any ideas?
Thank you
public void postMail(String recipient, String subject, String message, String from) throws MessagingException, UnsupportedEncodingException {
//Set the host smtp address
Properties props = new Properties();
props.put("mail.smtp.host", "mail.infodim.gr");
// create some properties and get the default Session
Session session = Session.getDefaultInstance(props, null);
// create a message
Message msg = new MimeMessage(session);
// set the from and to address
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress addressTo=new InternetAddress(recipient);
msg.setRecipient(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
Try:
msg.setContent(message, "text/plain; charset=UTF-8");
Edit Changed to text/plain.
Instead of
msg.setContent(message, "text/plain");
I would write
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = new MimeBodyPart();
mbp.setContent(message, "text/plain; charset=ISO-8859-7");
mp.addBodyPart(mbp);
msg.setContent(mp);
I guessed ISO-8859-7 from your name because this charset is for Greek, but maybe you can choose it more properly. Or maybe also UTF-8 works for your case.
If nothing else helps, try changing an encoding of your source files (including .java files) to UTF8.
In Eclipse it is done via Window -> Preferences -> General -> Workspace : Text file encoding
I had CP1252 as a default for my text files.
I am getting my text from .properties files. Changing them to UTF8 didn't help.
This is insane, but switching my .java files to UTF8 solved my issue!