Tuesday, January 7, 2014

Struggling with NoSuchProviderException: smtp or UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed ?

If you have faced with any of the above exceptions this blog post may be a little help for you to clear out some dark areas as I will list out some helpful posts/forums/articles that I ran through to chase away above two nasty fellows. But the main reason for writing this blog post is as a note to myself how I got through the above scary exceptions. 

I came across the above two exceptions when I was asked to go through this issue. The jaggery pom file that this jira is referring was this. As said in the jira when the jaggery level email feature is enabled, Axis2 email transport is not working and throwing the above said exception of 

ERROR {org.apache.axis2.transport.mail.MailTransportSender} - Error creating mail message or sending it to the configured serverjavax.mail.NoSuchProviderException: smtpat javax.mail.Session.getService(Session.java:782)at javax.mail.Session.getTransport(Session.java:708)at javax.mail.Session.getTransport(Session.java:651)
..............................

As commented in the jira when I remove the below three lines in jaggery pom file under the export package header, Axis2 email transport started to function without any issue.

com.sun.mail.imap;version="2.0.0.wso2v1", 
com.sun.mail.pop3;version="2.0.0.wso2v1", 
com.sun.mail.smtp;version="2.0.0.wso2v1", 

But after removing those lines I tested the jaggery level email feature with a sample application and it had break the jaggery email feature with the same exception as NoSuchProvider found in jaggery Rhino Engine as follows.

ERROR {org.jaggeryjs.scriptengine.engine.RhinoEngine} -  org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.mail.NoSuchProviderException: smtp (/Test//Test.jag#13)
[2013-12-23 10:09:21,600] ERROR {org.jaggeryjs.jaggery.core.manager.WebAppManager} -  org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.mail.NoSuchProviderException: smtp (/Test//Test.jag#13)
..........................................

So that made sense when these exports are there, Axis2 email transport picks the wrong bundle at the class loading which is exported from jaggery. ( Where axis2 needs those bundles of version 1.4.0 it picks that of version 2.0.0.wso2v1) 

Then I thought of going ahead with fixing jaggery level email feature to work without the above three exports. Because even though those bundles were exported, they were used no where in jaggery. So there must be some misery why we have exported these in jaggery pom file.

To explore what is going behind the scene I played a bit with the pom file by removing all mail related imports/exports and etc as all those are coming from axis2 email transport. And ended up with the following exception.

ERROR {org.jaggeryjs.scriptengine.engine.RhinoEngine} -  org.mozilla.javascript.WrappedException: Wrapped org.jaggeryjs.scriptengine.exceptions.ScriptException: javax.mail.MessagingException: IOException while sending message;
  nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed
boundary="----=_Part_0_1755306561.1387772655287" (/Test//Test.jag#13)


So then my journey started to chase after this exception and came across this forum post. Go through the below comment by Oleg which shed some light in to the problem.
(I will add a screen shot of part of the reply for you to identify which one I'm talking about as there are many replies by Oleg )  





Go ahead reading the complete answer by Oleg. Although that answer ensured that this is some problem with class loading in OSGI level and also why we have exported those in jaggery level, still it didn't provide a solution to the problem.

Then this post came in to play.




Now the problem is more clear that this is due to buggy behavior of javax.activation and javax.mail in osgi level, due to issues in dynamic class loading. I could not go with the suggested approach due to some platform specific reasons of our code.

Finally the comments in this post became savior of mine.

So the send code is changed as given below.


         public void jsFunction_send() throws ScriptException { 
             ClassLoader classLoader = Thread.currentThread().getContextClassLoader();                                              Thread.currentThread().setContextClassLoader( javax.mail.Session.class.getClassLoader() );
             try {
                   message.setContent(multipart); 
                  Transport.send(message); 
             } catch (MessagingException e) {
                  throw new ScriptException(e); 
             } finally
                  Thread.currentThread().setContextClassLoader(classLoader);
             } 
      }



Done with the self note :)  In-case you need to go through the current code, my pom file is here and java class is here.

Acknowledgement
Many thanks to Pradeep, Kishanthan and Rajith from WSO2 for their help.


No comments:

Post a Comment