I am trying to use Play Framework to send out email. In applications.conf, when I set smtp.mock=true , it works perfectly well:
[info] application - HTML: Welcome to Play20StartApp. <br> Click on this link : http://localhost:9000/confirm/d77ea256-0d2e-4df5-b66e-e034159f8042 to confirm your email.<br><br>--<br>null
[debug] application - Mail sent - SMTP:smtp.google.com:465 SSL:yes user:username#gmail.com password:password
However, when I comment smtp.mock=true and attempt to send real emails, I get this error:
[debug] application - Mail.sendMail: Mail will be sent to user1#gmail.com
[ERROR] [09/26/2013 03:46:05.014] [application-akka.actor.default-dispatcher-2] [TaskInvocation] From address required
org.apache.commons.mail.EmailException: From address required
I have set smtp.user to a proper value, i.e. server#businessdomain.com . Any idea what causes this error?
Troubleshooting steps
The emails used are real emails, for the purpose of posting, they are anonymized. Likewise, a real domain name is used
Tested with a working local mail server (exim), as well as directly sending through Gmail (smtp.google.com) and Google Apps (aspmx.l.google.com) servers. These settings have been verified using mail clients.
The Java code snippet below works perfectly,
import java.util.;
import javax.mail.;
import javax.mail.internet.;
import javax.activation.;
public class SendEmail
{
public static void main(String [] args)
{
String to = "recipient#mydomain.com";
String from = "sender#mydomain.com";
String host = "localhost";
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
try{
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject("Subject of email");
message.setText("This is actual message");
Transport.send(message);
System.out.println("Sent message successfully....");
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
In the event that you are wrapping your mailer action in a Future (or Play Java equivalent), then it may be a variable scoping issue that you're hitting:
This works:
val mail = use[MailerPlugin].email
val async: Future[Unit] = Future{
mail.setSubject(subject)
mail.setRecipient(recipient)
mail.setFrom(from)
mail.send(body)
}
async.onFailure{case(e)=>
Logger.error(s"mailer failed for $recipient due to: ${e.getMessage}")
}
This does not work:
val mail = use[MailerPlugin].email
mail.setSubject(subject)
mail.setRecipient(recipient)
mail.setFrom(from)
val async: Future[Unit] = Future{mail.send(body)}
async.onFailure{case(e)=>
Logger.error(s"mailer failed for $recipient due to: ${e.getMessage}")
}
I assumed that the enclosing scope would be available within the Future closure; in this case definitely not since underlying Apache Commons mailer bails with "From address required". Sure enough, setting smtp.mock=true reveals that fromAddress is null when mail.setFrom and friends are populated outside of Future{...} scope.
Interestingly, even if I break out async val into a local method and pass in constructed mailer and body text:
private def async(mail: MailerAPI, body: String): Future[Unit] = Future{
mail.send(body)
}
the mail properties set outside of the Future still wind up null despite passing a constructed mailer directly -- surprising, no?
Related
Good day,
I am self-taught with the help of a few free online courses in Java and very new to everything.
I'm struggling to run a code that's meant to send emails with a set content using my PC as localhost. using Netbeans IDE, I keep getting the following:
"Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement
at SendEmail$Session.getDefaultInstance(SendEmail.java:29)
at SendEmail$Session.access$000(SendEmail.java:27)
at SendEmail.main(SendEmail.java:16)
C:\Users\ameer.hussein\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)"
I'm not sure what to do as I've tried multiple methods to overcome this issue and have a successful application. I've done what I know and can count on from my notes but still dont understand what this exception means.
the code im trying to run:
public class SendEmail {
public static void main(String [] args) {
String to = "example#email.com, example#email.com";
String from = "example#email.com";
String host = "localhost";
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....");
}
}
void addRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException
Can someone please help me understand the exception and why it occurs?
Kind Regards,
Ameer
I have used java mail API for sending mail in my application using java and web driver.My requirement is to send a mail whenever a link/url is down.Even though mail is send when i give url incorrectly ,but at the same time if a url is not loading due any other issue (page not found), found that mail is not getting send.
public void SendMail(String url,String str)
{
try
{
Sheet mailsheet = w.getSheet("mail");
String from = mailsheet.getCell(0,1).getContents().toString().trim();
String toEmailID=mailsheet.getCell(1,1).getContents().toString().trim();
Properties props = new Properties();
String mailprotocol = mailsheet.getCell(2,1).getContents().toString().trim();
String mailprotocoltype = mailsheet.getCell(3,1).getContents().toString().trim();
String mailhost = mailsheet.getCell(4,1).getContents().toString().trim();
String mailhostip = mailsheet.getCell(5,1).getContents().toString().trim();
String mailport=mailsheet.getCell(6,1).getContents().toString().trim();
String mailportid=mailsheet.getCell(7,1).getContents().toString().trim();
props.put(mailprotocol,mailprotocoltype);
props.put(mailhost,mailhostip);
props.put(mailport,mailportid);
javax.mail.Session mailSession =javax.mail.Session.getInstance(props);
Message msg = new MimeMessage(mailSession);
msg.setFrom(new InternetAddress(from));
msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(toEmailID));
msg.setSubject("Test Summary");
msg.setContent("<html><body>Dear Admin,<br> Website page "+ "<b><i>"+url + "</b></i>"+" cannot be loaded due to the following :<br> <br></body></html>"+str,"text/html");
Transport.send(msg);
System.out.println("Mail is successfully sent to Recipient address with Error information.");
}
catch(Exception e)
{
//System.out.println(e);
System.out.println("Mail cannot be send to Recipient address due to connection error");
}
}
public void x() {
SendMail(url,driver.getTitle());
}
The answer is probably in the bit of code you don't show us : the part where you test the URL.
The response code for a wrong domain name is different from the response code due to a page not found. Also, depending on the system you're targetting, it's possible that page not found are redirected to the index page, making detection even more difficult.
I'm writing a small Java app using JavaMail that sends the user an automated email. They can choose between (for now) two ports: 25 and 587. The port can be selected via a radio button on the GUI.
I added a test button to allow the user to test the email settings (including port). However, for some reason, once the user tries to send a test email, the port can't be changed. Javamail will always use the port of the original test email.
Example: User tries to send an email on port 25 and JavaMail says it can not connect on port 25 (for example, the SMTP host uses another port). User clicks port 587, and tries to send a new email. JavaMail throws an error saying it can not connect on port 25, again.
I'm kind of stumped as to why. Every time a new test email is sent an entirely new SendMailUsingAuthentication object is created. Within that class the properties are always reset to the proper port. Whenever I debug, as far as I can see, all variables are correct and associated with the correct port. Is there something going on inside of Transport that I'm missing?
In the front end GUI:
private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = port25RadioButton.isSelected() ? PORT_25 : PORT_587;
notifier = new SendMailUsingAuthentication(hostNameTextField.getText(),
userTextField.getText(), getPassword(), emailTextField.getText().split(","),port);
Thread wait = new Thread(new Runnable() {
public void run() {
try {
changeStatusText("Sending test email...");
notifier.postTestMail();
changeStatusText("Test email sent.");
} catch (AddressException ex) {
changeStatusText("Error. Invalid email address name.");
} catch (MessagingException ex) {
changeStatusText("SMTP host connection refused.");
System.err.println(ex.getMessage());
} catch (Exception ex) {
System.err.println(ex);
}
}
});
wait.start();
}
In the email sender class:
public void postTestMail() throws MessagingException, AddressException{
String[] testReciever = new String[1];
testReciever[0] = emailList[0];
postMail(testReciever, "Test email.", "Your email settings are successfully set up.", emailFromAddress);
}
private void postMail(String recipients[], String subject,
String message, String from) throws MessagingException, AddressException {
//Set the host smtp address
Properties props = new Properties();
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.host", smtpHostName);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", true);
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
session.setDebug(false);
// 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[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
This happens because you're using getDefaultInstance() which says:
Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default.
And that the Properties argument is "used only if a new Session object is created."
So the first time you invoke getDefaultInstance it uses your specified port. After that, the Session has already been created, and subsequent calls to getDefaultInstance will return that same session, and ignore the changed properties.
Try using Session.getInstance() instead of getDefaultInstance(), which creates a new Session each time, using the supplied properties.
It pays to read the javadocs very carefully.
Tip for anyone else still having issues, we were using Session.getInstance and the port was still defaulting to 25.
Turns out, we were setting the prop value as a Long when it needs to be a String
It didn't error, warn or log, just defaulted to 25.
I think "Transport.send(msg)" wont be taking into account the connection details that you are providing in your properties. It will use its connection that is defined by default.
The java doc says
"Note that send is a static method that creates and manages its own connection. **Any connection associated with any Transport instance used to invoke this method is ignored and not used. This method should only be invoked using the form Transport.send(msg);, and should never be invoked using an instance variable. "**
Instead, I have tried with Transport.connect(smtphost,smtpport,user,password) and it works pretty well.
Plz compare two methods of Session class: Session.getDefaultInstance(Properties, Authenticator) and Session.getInstance(Properties, Authenticator)
I am using Java mail API to send email through my java application. But I want to send it automatically on future date i.e. any specific date of every month/year. I have used my ISP's SMTP server to send email on mentioned id.I have referred the below available example on net. How to set any specific date here.I have tried SimpleDateFormat and set it here but it still sends mail immediately but set its sent date as mentioned specific date. Is there any other way to send automatic email on mentioned date and time?
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
// Send a simple, single part, text/plain e-mail
public class TestEmail {
public static void main(String[] args) {
// SUBSTITUTE YOUR EMAIL ADDRESSES HERE!!!
String to = "abc#abc.com";
String from = "abc#abc.com";
// SUBSTITUTE YOUR ISP'S MAIL SERVER HERE!!!
String host = "smtp.yourisp.net";
// Create properties, get Session
Properties props = new Properties();
// If using static Transport.send(),
// need to specify which host to send it to
props.put("mail.smtp.host", host);
// To see what is going on behind the scene
props.put("mail.debug", "true");
Session session = Session.getInstance(props);
try {
// Instantiatee a message
Message msg = new MimeMessage(session);
//Set message attributes
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("Test E-Mail through Java");
msg.setSentDate(new Date());
// Set message content
msg.setText("This is a test of sending a " +
"plain text e-mail through Java.\n" +
"Here is line 2.");
//Send the message
Transport.send(msg);
}
catch (MessagingException mex) {
// Prints all nested (chained) exceptions as well
mex.printStackTrace();
}
}
}//End of class
Configure Quartz Job for it. Use cron trigger to specify the execution event
If you're using an EJB 3.0+ container, you could easily use the timer service.
You need to make a session bean, and either implement the TimedObject interface or annotate a method with #Timeout. You can get an instance of the TimerService from the InitialContext via getTimerService(), then create a timer with one of the createTimer() variants. It can take an interval, or a Date object specifying when it expires...
I am looking for a Java class that will allow me to send emails without the need for SMTP. Like the PHP mail() class that uses sendmail.
Any suggestions?
Many Thanks
James
Before Using this Program, you need to have Javasoft's JavaMail class files which can be downloaded from here http://www.javasoft.com/products/javamail/index.html
You will also need the JavaBeansTM Activation Framework extension or JAF (javax.activation). It is available at http://java.sun.com/beans/glasgow/jaf.html.
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public void postMail( String recipients[ ], String subject, String message , String from) throws MessagingException
{
boolean debug = false;
//Set the host smtp address
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.jcom.net");
// create some properties and get the default Session
Session session = Session.getDefaultInstance(props, null);
session.setDebug(debug);
// 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[recipients.length];
for (int i = 0; i < recipients.length; i++)
{
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Optional : You can also set your custom headers in the Email if you Want
msg.addHeader("MyHeaderName", "myHeaderValue");
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
I found it:
http://examples.oreilly.com/jenut/SendMail.java
Thanks all.
All mail senders will need an SMTP server to transfer their mail. The nice thing about PHP mail is that you don’t need to configure it (it use the sendmail binary directly, if sendmail is not installed, PHP mail will not work either).
If all you want is building a Java application that can send out e-mail without configuring an SMTP server for that, you could use a Java based SMTP server, for example:
Apache James