IncompatibleClassChangeError from okhttp3.internal.Util.clos



在旧版本的Android(4.3及更早版本)上看到以下堆栈:

Caused by: java.lang.IncompatibleClassChangeError: interface not implemented
at okhttp3.internal.Util.closeQuietly(Util.java:100)
at okhttp3.internal.connection.StreamAllocation.streamFailed(StreamAllocation.java:332)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.recover(RetryAndFollowUpInterceptor.java:209)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:132)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
at okhttp3.RealCall.execute(RealCall.java:63)

这似乎表明okhttp和Java 6之间不兼容,java.net.Socket没有实现Closeable

问题似乎主要是由于流失败而发生的。在我们开始调用这个 php 页面(借用自 https://stackoverflow.com/a/141026/315702)之前,很难重现,这迫使客户端出现流故障:

<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
sleep(30);
echo('Text user will never see');
?>

这似乎是当前 okhttp 3.6.0-SNAPSHOT 构建中的一个错误。我在okhttp github网站上提交了一份错误报告。当连接意外关闭时,将引发异常。[更新:通过在此拉取请求中将 Closeable 替换为 Socket 以向后兼容 Java 6,该错误得到了快速修复。

在我们的案例中,问题的真正核心是我们一开始就没有打算使用 okhttp 3.6.0-SNAPSHOT。在我们的build.gradle中,我们指定了 3.4.1。事实证明,我们的一个第三方库依赖于 okhttp:+,我们通过以下 gradle 命令发现了它:

./gradlew -q :app:dependencyInsight --dependency okhttp --configuration compile

正因为如此,我们一直在引入最新版本的okhttp。在我们的例子中,罪魁祸首库是 exoplayer 的 okhttp 扩展。通过排除对okhttp:+的不需要的模块依赖,我们能够避免加载3.6.0-SNAPSHOT:

compile('com.google.android.exoplayer:extension-okhttp:r2.0.4') {
    exclude module: 'okhttp'
}

相关内容

最新更新