シーンの説明:
メールボックス構成を保存するときに、メールボックス構成パラメーターが正しいかどうかが自動的に検出されます。SMTP を検出すると、システムが次の例外を報告することがわかります。
次のようにコードをコピーします。
javax.mail.MessagingException: 501 コマンド「HELO」には引数が必要です
com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:1363) で
com.sun.mail.smtp.SMTPTransport.helo(SMTPTransport.java:838) で
com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:375) で
javax.mail.Service.connect(Service.java:275) で
しかし、Windows サーバーに変更したところ、この問題は Linux サーバーでのみ再現できることがわかりました。直感的には、この Linux サーバーの構成に問題があるように思えました。
トラブルシューティングの手順
1. 同じオペレーティング システムを搭載した Linux サーバーを見つけて、電子メールの設定を確認し、[OK] をクリックして、Linux オペレーティング システムの特殊性に関する問題を解決します。
2. Linux サーバー上で直接 Telnet を使用して、反対側のメール サーバーの SMTP ポートに接続します。サーバーのネットワークの問題をトラブルシューティングします。
3. HELO 命令の説明を見つける
次のようにコードをコピーします。
こんにちは
-- このコマンドを使用する場合、メール サーバーがユーザーを認識できるように、ドメイン名を指定できます。たとえば、HELO mailhost2 です。
SMTP サーバーにメッセージの送信元を伝えるには、HELO コマンドの後にイニシエーターのホスト名を続ける必要があることがわかりました。
例外メッセージ「501 コマンド "HELO" には引数が必要です」を見ると、プログラムが SMTP サーバーとの対話中にソース ホスト ドメイン名を渡さなかったことは明らかです。
4. JAVA MAIL のソースコードを表示する
次のように HELO 命令を見つけます。
次のようにコードをコピーします。
/**
* <code>HELO</code> コマンドを発行します。
*
* @param ドメイン
* 当社のドメイン
*
* @JavaMail 1.4.1以降
*/
protected void helo(String ドメイン) throws MessagingException {
if (ドメイン != null)
issueCommand("HELO " + ドメイン, 250);
それ以外
issueCommand("HELO", 250);
}
hello メソッドが呼び出される場所を見つけて、ドメインがどのように渡されるかを確認します。
次のようにコードをコピーします。
if (イーロを使用)
成功 = ehlo(getLocalHost());
if (!成功)
hello(getLocalHost());
当然のことながら、次のように定義されている getLocalHost() メソッドを探します。
次のようにコードをコピーします。
/**
* EHLO および HELO コマンドで使用するローカル ホストの名前を取得します。
* プロパティ mail.smtp.localhost は mail.smtp.localaddress をオーバーライドします。
* InetAddress が通知する内容をオーバーライドします。
*/
public synchronized String getLocalHost() {
試す {
// ホスト名を取得し、将来の使用のためにキャッシュします
if (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + name + ".localhost");
if (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + name+ ".localaddress");
if (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getHostName();
// 名前を取得できない場合は、ローカル アドレス リテラルを使用します
if (localHostName == null)
// XXX - IPv6 には正しくありません
localHostName = "[" + localHost.getHostAddress() + "]";
}
} catch (UnknownHostExceptionuex) {
}
ローカルホスト名を返します。
}
ホスト名は現在の接続のセッション属性、または現在のサーバーのホスト構成から取得できることがわかります。ただし、このプログラムではセッションにホスト名を設定しないため、その理由はホスト ファイルにあるはずです。 Linux サーバーのファイルが変更されたため、JAVA プログラムが localhostName を自動的に取得できなくなりました。
5. /etc/hosts ファイルを確認します。状況は次のとおりです。
次のようにコードをコピーします。
127.0.0.1 localhost.localdomain ローカルホスト
::1 ローカルホスト6.ローカルドメイン6 ローカルホスト6
次のように hosts ファイルを変更するだけです。
次のようにコードをコピーします。
127.0.0.1 ローカルホスト
::1 ローカルホスト6.ローカルドメイン6 ローカルホスト6
6. 再テストすると問題は解決します。
実際、この状況はプログラミングによって回避することもできます。つまり、現在のサーバーのホスト名属性をセッション接続に追加します。プログラム例は次のとおりです。
次のようにコードをコピーします。
public static void main(String[] args) {
試す {
int smtpport = 25;
文字列 smtpserver = "219.147.xxx.xxx";
プロパティ prop = System.getProperties();
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.localhost", "myMailServer");
セッション mailSession = Session.getInstance(prop, null);
トランスポート Transport = mailSession.getTransport("smtp");
Transport.connect(smtpserver,smtpport, "ユーザー名", "パスワード");
System.out.println("接続OK");
Transport.close();
} catch (AuthenticationFailedException en) {
en.printStackTrace();
System.out.println("SMTPサーバー接続に失敗しました。入力情報が正しいか確認してください");
} catch (NoSuchProviderException e) {
e.printStackTrace();
System.out.println("SMTPサーバー接続に失敗しました。入力情報が正しいか確認してください");
} catch (MessagingException e) {
e.printStackTrace();
System.out.println("SMTPサーバー接続に失敗しました。入力情報が正しいか確認してください");
}
}