Java Mail サーブレットを実装しようとしています。最初のステップは IMAP サーバーに接続することです。
ポート 143 (デフォルトの IMAP ポート) でサーバーに telnet できます。telnet は次のように述べています。OK The Microsoft Exchange IMAP4 service is ready.
今、次のようにJava Mail APIを使用してサーバーに接続しようとしています:
Properties props = new Properties();
session = Session.getDefaultInstance(props, null);
store = session.getStore("imap");
store.connect("host","user","password");
そして、Javaで渡そうとしているのと同じ資格情報を持つ既存のOutlook Webappを使用して、この同じサーバーに接続できます。
ただし、これを実行するとsession.setDebug(true)
、次の出力が生成されます。
DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null>
javax.mail.MessagingException: No login methods supported!;
編集:
prop.setProperty("mail.imap.starttls.enable", "true")
提案通り追加しました。
ただし、次のデバッグ出力を取得し始めました。
DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: enable STARTTLS
DEBUG: trying to connect to host "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null>
A1 STARTTLS
A1 OK Begin TLS negotiation now.
DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
これが証明書の問題であると仮定して、これらの指示に従い、メール サーバーを自分の cacerts ファイルに追加しました。そこに含まれているテスト プログラムは問題なく動作し、SSL URL を使用して接続できましたが、Java メール クラスを実行すると同じ例外が発生しました。
また、(「imap」の代わりに)「imap」に変更しようとしましsession.getStore("imaps")
たが、「Microsoft Exchange Server is now ready」というメッセージを取得することさえできませんでした。「imaps」が指定されるたびにポート993で接続しようとしているからだと思います。しかし、ポート 993 に telnet を使用しても、電子メール サーバーへの接続は表示されません。
次に、次のように、プログラムがポート 143 で SSL を使用するように強制しようとしました。
// Use SSL
prop.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.fallback", "false");
// Use port 143
prop.setProperty("mail.imap.port", "143");
prop.setProperty("mail.imap.socketFactory.port", "143");
この例外を受け取るためだけに、SSL とは何の関係も望んでいないと思います。
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "myHost", port 143, isSSL false
Not able to process the mail reading.
javax.mail.MessagingException: Unrecognized SSL message, plaintext connection?;
上記の TLS 例外 ( DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException:
) は、Exchange サーバーで TLS が有効になっていないことが原因でしょうか?
私は電子メール サーバーにアクセスする準備ができていませんが、誰かに許可してもらうことはできるでしょう。
解決:
彼の回答の下にあるHulkingUnicornのコメントは、必要な正確な処理であるこの回答を指摘しました。明らかに、MS Exchange Server にはこの問題があります。その回答にリストされているクラスをパッケージに追加するとともに、次のようにメール接続を実装しただけで、すべてうまくいきました。
Properties prop = new Properties();
prop.setProperty("mail.imap.starttls.enable", "true");
prop.setProperty("ssl.SocketFactory.provider", "my.package.name.ExchangeSSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.class", "my.package.name.ExchangeSSLSocketFactory");
session = Session.getDefaultInstance(prop, null);
session.setDebug(true);
store = session.getStore("imap");
store.connect("myHost","myUser","myPassword");