Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Tomcat find SMTPTransport(Session, URLName)?

We've got a web application that sends mail. For some reason, an installation of it has decided that it can't find the constructor for SMTPTransport that takes (Session,URLName) arguments.

Relevant bits of the stack trace:

 javax.mail.NoSuchProviderException: Provider class does not have a constructor(Session, URLName): protocol=smtp; type=javax.mail.Provider$Type@1dedf78; class=com.sun.mail.smtp.SMTPTransport; vendor=Sun Microsystems, Inc
        at javax.mail.Session.getService(Session.java:499)
        at javax.mail.Session.getTransport(Session.java:387)
        at javax.mail.Session.getTransport(Session.java:347)
        at javax.mail.Session.getTransport(Session.java:376)
        at javax.mail.Transport.send(Transport.java:67)
        at javax.mail.Transport.send(Transport.java:48)
...
Caused by: java.lang.NoSuchMethodException: com.sun.mail.smtp.SMTPTransport.<init>(javax.mail.Session, javax.mail.URLName)
        at java.lang.Class.getConstructor0(Class.java:2706)
        at java.lang.Class.getConstructor(Class.java:1657)
        at javax.mail.Session.getService(Session.java:496)
        ... 8 more

We've already checked that SMTPTransport does exist in the classpath (which is not surprising, since we're not getting a ClassNotFoundException), and that it is the only copy of that class in the classpath. It's in tomcat/lib. Our webapp does not include a duplicate. There is not a duplicate in $JAVA_HOME/jre/lib.

I've even gone so far as to decompile the class to verify that it does in fact have the Constructor in question.

I've done a bit of googling and have found other people who have seen the same error, but no fixes for the problem.

like image 797
Cody Casterline Avatar asked Sep 28 '11 15:09

Cody Casterline


1 Answers

My coworker and I figured out why we were seeing this. I posted about it here: https://plus.google.com/105513684958738872125/posts/LBnjehZoss6

In summary:

While I was looking for a duplicate SMTPTransport class, there was none to be found. The real culprit was a duplicate javax.mail.Session class that had gotten added to my webapp. This caused problems with Tomcat's hierarchical classloaders.

When the in-webapp Session class tried to pass itself off to the Tomcat-level SMTPTransport, that one didn't recognize that Session type (which had been loaded by a different classloader) as the type that it needed for its constructor.

Removing the duplicate javax.mail classes from the webapp fixes the problem.

like image 134
Cody Casterline Avatar answered Nov 10 '22 04:11

Cody Casterline