已經發現的問題是 JavaMail 在建立 Socket 連線時會噴以下的 Exception:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465 ; nested exception is: java.io.IOException: Can't create MailSSLSocketFactory at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java: 1966 ) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java: 654 ) at javax.mail.Service.connect(Service.java: 295 ) at javax.mail.Service.connect(Service.java: 176 ) at org.twgogo.jimwayne.mail.MailService.sendMail(MailService.java: 266 ) at org.twgogo.jimwayne.mail.MailService.sendMail(MailService.java: 157 ) at org.twgogo.jimwayne.main.Main.sendMail(Main.java: 52 ) at org.twgogo.jimwayne.main.Main.main(Main.java: 23 ) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 57 ) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43 ) at java.lang.reflect.Method.invoke(Method.java: 616 ) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java: 58 ) Caused by: java.io.IOException: Can't create MailSSLSocketFactory at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java: 344 ) at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java: 239 ) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java: 1929 ) ... 12 more Caused by: java.security.KeyStoreException: problem accessing trust storejava.io.EOFException at sun.security.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java: 75 ) at javax.net.ssl.TrustManagerFactory.init(TrustManagerFactory.java: 247 ) at com.sun.mail.util.MailSSLSocketFactory$MailTrustManager.<init>(MailSSLSocketFactory.java: 333 ) at com.sun.mail.util.MailSSLSocketFactory$MailTrustManager.<init>(MailSSLSocketFactory.java: 331 ) at com.sun.mail.util.MailSSLSocketFactory.<init>(MailSSLSocketFactory.java: 115 ) at com.sun.mail.util.MailSSLSocketFactory.<init>(MailSSLSocketFactory.java: 94 ) at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java: 337 ) ... 14 more |
我把建立 Socket 的程式碼獨立拿出來執行時,發現 Exception 變成以下的內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class : sun.security.ssl.DefaultSSLContextImpl) at javax.net.ssl.DefaultSSLSocketFactory.throwException(SSLSocketFactory.java: 196 ) at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java: 203 ) at org.twgogo.jimwayne.socket.SocketTester.createSocket(SocketTester.java: 16 ) at org.twgogo.jimwayne.main.TestMain.main(TestMain.java: 15 ) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 57 ) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43 ) at java.lang.reflect.Method.invoke(Method.java: 616 ) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java: 58 ) Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class : sun.security.ssl.DefaultSSLContextImpl) at java.security.Provider$Service.newInstance(Provider.java: 1262 ) at sun.security.jca.GetInstance.getInstance(GetInstance.java: 236 ) at sun.security.jca.GetInstance.getInstance(GetInstance.java: 164 ) at javax.net.ssl.SSLContext.getInstance(SSLContext.java: 142 ) at javax.net.ssl.SSLContext.getDefault(SSLContext.java: 85 ) at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java: 119 ) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 57 ) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43 ) at java.lang.reflect.Method.invoke(Method.java: 616 ) at org.twgogo.jimwayne.socket.SocketTester.getSocketFactory(SocketTester.java: 42 ) at org.twgogo.jimwayne.socket.SocketTester.createSocket(SocketTester.java: 15 ) ... 6 more Caused by: java.io.EOFException at java.io.DataInputStream.readInt(DataInputStream.java: 392 ) at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java: 645 ) at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java: 55 ) at java.security.KeyStore.load(KeyStore.java: 1201 ) at sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(TrustManagerFactoryImpl.java: 221 ) at sun.security.ssl.DefaultSSLContextImpl.getDefaultTrustManager(DefaultSSLContextImpl.java: 87 ) at sun.security.ssl.DefaultSSLContextImpl.<init>(DefaultSSLContextImpl.java: 57 ) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java: 57 ) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java: 45 ) at java.lang.reflect.Constructor.newInstance(Constructor.java: 532 ) at java.lang.Class.newInstance0(Class.java: 372 ) at java.lang.Class.newInstance(Class.java: 325 ) at java.security.Provider$Service.newInstance(Provider.java: 1238 ) ... 17 more |
看起來有點奇怪,因為獨立抽出來的程式碼中並沒有指定要用 SunJSSE 的東西
只有指定 SocketFactory 要用 javax.net.ssl.SSLSocketFactory。
而 Google 時看起來 OpenJDK 內建應該有 javax.net.ssl.SSLSocketFactory 這個 class
不知道為什麼程式跑一跑自己會跑去抓 SunJSSE。
雖然也有可能是本來就要去找 SunJSSE 的某些東西,但因為網路上搜尋時好像沒有看到有人說 JavaMail 在 OpenJDK 上沒辦法用
理論上應該比較有可能的還是我有哪裡弄錯了才對。
Still keep working!
2013-02-26 補充:
後來交給廠商處理,廠商說他們用的 OpenJDK 是自己客製化過的版本,所以並不是 OpenJDK 本身有問題...
他們更新了自己客製化的 OpenJDK 後,這個問題就消失了...。
後來雖然又有出現 Read timeout 的問題,但把 JavaMail 版本從 1.4.4 升級成 1.4.6 就好了
不知道是被什麼影響到的~原本我們自己的環境中用 Sun JDK 1.6.0 + JavaMail 1.4.4 一直都用得很好。
參考資料:
1、SSL with javamail not working
2、Is Java SSL broken in OpenJDK on Ubuntu?
沒有留言:
張貼留言