iMisty的技术栈

iMisty的技术栈

OkHttp与jdk版本不兼容分析与解决方案

3042
2020-10-26

前言

最近项目中有一段调用web Api的接口调用不通,发现在同事的电脑上正常自己出现如下错误clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on JDK 9+

排查得知自己的jdk版本是 java1.8.0_215, okhttp版本是 4.0.1 ,将okhttp降级为3.X,或者将jdk降版本可以解决这个问题,但是毕竟有点蠢;

出现问题的原因

  1. 代码中okhttp的trustHttps字段设置是true,代表信任所有的https连接。具体实现时
    c3673dcd.jpeg
  2. OkHttpClient.class中关于sslSocketFactory方法如下:
    726724d7.jpeg
  3. Platform.class中关于findPlatform方法如下:
    68390e9c.jpeg
  4. Jdk9Platform是Platform的子类。Jdk9Platform.class中buildIfSupported方法如下:
    efd1dae9.jpeg
  5. 在jdk1.8.0_251之前的版本中在步骤3 会直接通过new Platform()创建父类对象,之后就会调用父类中的trustManager方法:
    98e89a93.jpeg

OkHttp4.3.0 的优化

  1. Okhttp 4.X版本采用kotlin语言进行了编写,整体思路和Java版本区别不大。我们首先来看看okhttp是如何改进这个bug的:
    cabdbf26.jpeg

20532d70.jpeg

  1. 我们在来看看新版本是如何判断jdk9版本的: 采用了从系统读取Java的主版本号,判断是否大于9来实现的;

02f19a54.jpeg

解决方案

  1. 因为sslSocketFactory方法标记了@deprecated注解,重载的方法为:
    e04ce12e.jpeg
    重载方法将信任管理设为了输入参数。而且给出了使用建议:
    f9f3a71d.jpeg
    其实就是调用sslSocketFactory时候传入trustManager。(推荐此做法,无论okhttp、okhttp版本是什么,都不会报错)
    91940e71.jpeg

总结

  1. 将jdk降级到251一下,或者将okhttp升级到4.3版本以上或者降为版本3.X
  2. 调用sslSocketFactory时候传入trustManager, 推荐这个方法,这样无论在那个版本的OKhttp上都可以正确使用

鸣谢

感谢小伙伴提供的文档

OKhttp官方文档