Disruptive Disruptive - 4 months ago 80
Java Question

Unable to send async emails with Play 2.5

I recently migrated my application from play 2.3 to play 2.5 following this guide https://www.playframework.com/documentation/2.5.x/Migration25
and I update play-mailer too according to what specified here https://github.com/playframework/play-mailer

Now my app is no longer able to send emails. I created an Injector Constructor for injecting mailer instance

@Inject public SmtpConnector(MailerClient mailer)
{
this.mailerClient = mailer;
MailcapCommandMap mc = (MailcapCommandMap) MailcapCommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content- handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mc);
}


I execute the send email method in an async task:

CompletableFuture.runAsync( () -> mailerClient.send(email) ).exceptionally(exc -> {exc.printStackTrace(); return null;});


But I keep getting an error about the lack of suport about mimetype multipart:


...
java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626) ... 5 more Caused by: javax.mail.MessagingException: IOException while sending message; nested exception is: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative; boundary="----=_Part_0_1284684208.1469102367572" at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1177) at javax.mail.Transport.send0(Transport.java:195) at javax.mail.Transport.send(Transport.java:124) at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411) ... 14 more Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative; boundary="----=_Part_0_1284684208.1469102367572" at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:896) at javax.activation.DataHandler.writeTo(DataHandler.java:317) at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485) at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1773) at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1121) ... 17 more


But:



Is there a workaround to this? Is there a(nother) way to send emails using a java api with Play framework 2.5?

UPDATE 1:

According to jmehrens suggestion, I activated the debug flag, that's what I got:


Can't load DCH com.sun.mail.handlers.multipart_mixed;
Exception: java.lang.ClassNotFoundException: com/sun/mail/handlers/multipart_mixed


And according to this github.com/playframework/play-mailer/issues/104 the problem seems triggered by not calling the method from the context of the Play controller

UPDATE 2:
Here you can find the -verbose:class output from the start till the exception: s000.tinyupload.com/?file_id=50323853839855936002

UPDATE 3:

Here you can find the classloader of getClass() dumped as suggested by jmehrens: s000.tinyupload.com/?file_id=51200633758480523188

Answer

This fixes the issue:

CompletableFuture.runAsync( () -> {
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); 
mailerClient.send(email);}, Executors.newSingleThreadExecutor()).exceptionally(exc ->  {
exc.printStackTrace(); 
return null;});