2017-01-20 6 views
2

Sehen Sie die folgenden Stapel auf alte Versionen von Android (4.3 und früher):IncompatibleClassChangeError von okhttp3.internal.Util.closeQuietly()

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) 

Dies scheint eine Inkompatibilität zwischen okhttp und Java 6 vorzuschlagen, wo java.net.Socket implementiert Closeable nicht.

Und das Problem scheint hauptsächlich als Folge eines fehlgeschlagenen Streams auftreten. Es war schwer zu reproduzieren, bis wir den Aufruf diese PHP-Seite (entlehnt aus https://stackoverflow.com/a/141026/315702) gestartet, der einen Stromausfall auf der Client-Seite zwingt:

<?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'); 
?> 

Antwort

2

Dies scheint ein Fehler mit dem aktuellen okhttp 3.6.0-SNAPSHOT zu sein bauen. Ich habe eine bug report auf der Okhttp Github-Website abgelegt. Die Ausnahme wird ausgelöst, wenn die Verbindung unerwartet geschlossen wird. [Update: Der Fehler wurde schnell behoben, indem Closeable mit Socket für die Rückwärtskompatibilität mit Java 6 in diesem pull request ersetzt wurde.]

In unserem Fall war der eigentliche Kern des Problems, dass wir nicht okhttp 3.6 verwenden wollten. 0-SNAPSHOT an erster Stelle. In unserer build.gradle haben wir 3.4.1 angegeben. Es stellte sich heraus eine unserer Bibliotheken von Drittanbietern hatte eine Abhängigkeit von okhttp: +, das wir über die folgenden gradle Befehl entdeckt:

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

Aus diesem Grund haben wir in zogen, was auch immer passiert, das neueste zu sein Version von okhttp. In unserem Fall war die Schuldbibliothek die Erweiterung des Exoplayers. Durch den Ausschluss der unerwünschten Modul Abhängigkeit von okhttp: + konnten wir Laden 3.6.0-SNAPSHOT vermeiden:

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

FWIW, es sieht aus wie sie verzichteten '+' zum Zeitpunkt des 'r2.1.1'. BTW, schöne Analyse! – CommonsWare

+0

Es brauchte den kollektiven IQ von mehreren Entwicklern, um auf den Grund dieses zu kommen. Und danke - ich wollte nachsehen, ob die '+' Abhängigkeit behoben wurde! – markproxy

+2

Festgelegt hier: https://github.com/square/okhttp/pull/3125 –

Verwandte Themen