Java7とJavaMail

Java7でJavaMailを使うと、以下のようなエラーでSMTPサーバへの接続が失敗します。

javax.mail.MessagingException: Could not connect to SMTP host: 192.168.151.201, port: 25;
nested exception is:
java.net.SocketException: Network is unreachable: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1282)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:370)
at javax.mail.Service.connect(Service.java:275)
at javax.mail.Service.connect(Service.java:156)
at javax.mail.Service.connect(Service.java:105)
at javax.mail.Transport.send0(Transport.java:168)
at javax.mail.Transport.send(Transport.java:98)
...

Caused by: java.net.SocketException: Network is unreachable: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:69)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:232)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:189)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1250)
... 11 more

なぜかLinuxマシンではエラーが出ず、Windowsマシンでのみ発生。
念のためtelnetSMTPを喋ってみたら、正しく接続できる。

調べてみたら以下の記事を見つけました。

Java Mail mystery - SMTP blocked?
http://stackoverflow.com/questions/14064111/java-mail-mystery-smtp-blocked

どうもJava7になってから、IPv6ネットワークアダプタが存在する場合にそっちを優先的に使おうとするようですね。WindowsはXPの頃からIPv6がデフォルトで(使ってなくても)設定されますから。

Javaの起動オプションで

-Djava.net.preferIPv4Stack=true

を指定することで解決。

または、プログラム内から以下を呼び出すことでも同じ結果が得られるようです。

System.setProperty("java.net.preferIPv4Stack", "true");

JavaMail API

JavaMail API

Java Mail完全解説

Java Mail完全解説