java.lang.NoSuchMethodError com.sun.mail.util.TraceInputStream
在用java實現發送郵件功能時,jdk1.8的兩臺windows主機上可以正常工作,在jdk1.7的Ubuntu主機上,發送郵件時就會拋異常:
java.lang.NoSuchMethodError: com.sun.mail.util.TraceInputStream.(Ljava/io/InputStream;Lcom/sun/mail/util/MailLogger;)V
at com.sun.mail.smtp.SMTPTransport.initStreams(SMTPTransport.java:2014)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1936)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:654)
at javax.mail.Service.connect(Service.java:291)
at ...
pom中引入的jar包如下:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mailapi</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.0</version>
</dependency>
這個錯誤其實是很明顯的jar包衝突引起的,度娘也說了:說javaEE5已經帶了這個方法,但有問題,而程序又沒有去加載你pom中的jar,所以就找不到這個類了。Google一下的解決方案是:
By default, Java apps running on latest Heroku stack use OpenJDK 8.
Your problem does not seems related to the actual JVM implementation but rather due to the missing smtp-1.5.1.jar in classpath . To be sure to load correctly TraceInputStream try this :
java.net.URL classUrl = this.getClass().getResource("com.sun.mail.util.TraceInputStream");
out.println(classUrl.getFile());
我大概明白它的意思其實是去加載你用pom下的jar包裏面的這個class,讀者也可以嘗試用ClassLoader去加載一下這個class試一下,其實,筆者這裏用了一個比較變態的不靠譜方法:
我在項目裏新建了一個與TraceInputStream同包同名的類,代碼原封不動,其實這裏的解決方案的本質,也是用到了java的ClassLoader機制,AppClassLoader加載了我的項目的類,自然就不再加載第三方(非java核心類庫)中的同一個類,然後程序自然就能找到上面那個Class了。
後面有時間的話,會研究一下用ClassLoader來加載這個Class,感覺這樣更靠譜些,您說呢?