SocketException:连接在 JRE 1.6 上重置,而不是在 JRE 11 上重置

SocketException: Connection reset on JRE 1.6, not on JRE 11

我有一个相当老旧的 Twitter 机器人,已经 运行 好几年没问题了。它在 JRE 1.6 上使用 twitter4j,运行。两天前我突然开始收到 SocketExceptions:

Exception in thread "main" Connection reset
  Relevant discussions can be found on the Internet at:
  http://www.google.co.jp/search?q=7e95ed42 or
  http://www.google.co.jp/search?q=8a72206c
TwitterException{exceptionCode=[7e95ed42-8a72206c faf0771e-c3d1e8db], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=4.0.7}
  at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:185)
  at twitter4j.HttpClientBase.request(HttpClientBase.java:57)
  at twitter4j.HttpClientBase.get(HttpClientBase.java:75)
  at twitter4j.TwitterImpl.get(TwitterImpl.java:2084)
  at twitter4j.TwitterImpl.getFriendsList(TwitterImpl.java:808)
  at twitter4j.TwitterImpl.getFriendsList(TwitterImpl.java:803)
  at uk.co.twinance.Fetcher.getAvatars(Fetcher.java:167)
  at uk.co.twinance.Fetcher.run(Fetcher.java:103)
  at uk.co.twinance.Fetcher.main(Fetcher.java:203)
Caused by: java.net.SocketException: Connection reset
  at java.net.SocketInputStream.read(SocketInputStream.java:168)
  at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:422)
  at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:460)
  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:863)
  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
  at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
  at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
  at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
  at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
  at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
  at twitter4j.HttpResponseImpl.<init>(HttpResponseImpl.java:35)
  at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:149)
  ... 8 more

我在我的 linode 和两台家用笔记本电脑 运行 Ubuntu 11 和 18 上得到了这个,并且我得到了每个请求的异常。

经过多次尝试后,我发现如果我将运行时切换到 JRE 11,它可以完美运行!完全没有例外。

所以 - 我猜 Twitter 端最近发生了一些变化(考虑到该问题在 3 台机器上可重现),但我无法理解 JRE 如何影响网络请求,从而导致推特的问题。

有什么想法吗?

您的问题是以下问题的组合:

  1. Java 6.0 仅支持 SSL/TLS 到 TLS1.0;参见 How to use TLS 1.2 in Java 6

  2. 2019 年 7 月 15 日星期一,Twitter 在其 public API 中关闭了对 TLS 1.0 和 TLS 1.1 的支持。 (来源 https://www.thesslstore.com/blog/twitter-will-deprecate-support-for-tls-1-0-tls-1-1-on-july-15/

综合起来,这就解释了为什么您的基于 Java 6 的 Twitter 机器人最近停止工作了。


请注意 Java 6.0 已停产。 Public 更新于 2013 年 4 月结束。甚至 Oracle 的 "Extended Support" Java 6.0 选项也在 2018 年 12 月停止。

(来源:https://www.oracle.com/technetwork/java/java-se-support-roadmap.html

因此,解决您的问题的最佳方法是更新运行您的 Twitter 机器人的 Java 平台。 (事实证明,升级很简单。)

升级Java还有另一个好处。您将对您的 Java 平台应用大约 6 年积累的安全补丁、错误修复和性能增强。


另请注意,TLS 1.2 已于 2008 年完成。最新版本是 TLS 1.3(2018 年完成)。 TLS 1.0 和 TLS 1.1 将于 2020 年正式弃用。

(来源https://en.wikipedia.org/wiki/Transport_Layer_Security

SSL/TLS 等关键互联网标准的不断发展是建议不要让 Java 平台落后太多的另一个原因。